postgresql - 如果唯一,如何选择行?
问题描述
我正在尝试进行两部分查询并返回分号分隔的列值的文本数组。
首先,根据三列的值仅选择唯一的行(即,如果三个值的元组不止一次存在,则它不是唯一的)。在剩余的行中,根据第四列执行另一个过滤器。
这就是我的想法,但也许有更好的解决方案。
我已经尝试了几种不同的方法。我目前的尝试是使用 CTE:
with uniqe as (
select distinct on (
col1,
col2,
col3
) *
from MyTable
)
select concat(col::text, ';', col2::text, ';', col3)
as key
from uniqe
where upper(dateRange) <= (now() - interval '1 days')
order by key;
我遇到的问题是,SELECT DISTINCT ON (col1, col2, col3) ...
似乎至少选择了 1 行我不认为是“独特”的其他行。
为了清楚起见,这是一个示例表:
id | col1 | col2 | col3 | dateRange
-----+------+------+------+-------------------------------------------------------
1 | 1 | 1 | A | ["2018-12-31 16:01:40-08","2018-12-31 16:03:20-08")
2 | 1 | 1 | A | ["2018-12-31 16:01:40-08","2018-12-31 16:03:20-08")
3 | 1 | 1 | B | ["2018-12-31 16:01:40-08","2018-12-31 16:03:20-08")
4 | 1 | 2 | A | ["2018-12-31 16:01:40-08","2018-12-31 16:03:20-08")
5 | 2 | 1 | A | ["2018-12-31 16:01:40-08","2018-12-31 16:03:20-08")
6 | 2 | 1 | A | ["2018-12-31 16:01:40-08","2018-12-31 16:03:20-08")
7 | 1 | 2 | B | ["2018-12-31 16:01:40-08","2018-12-31 16:03:20-08")
8 | 1 | 2 | B | ["2018-12-31 16:01:40-08","2018-12-31 16:03:20-08")
我认为第 3 行和第 4 行是唯一的唯一行。
解决方案
本质上,问题归结为根据聚合或窗口函数的值选择行。因此,这里的解决方案是适用的,除了在我们的例子中我们想要count(*)
等于 1。
因此,我们可以使用以下WHERE IN
方法:
WITH uniqe AS (
SELECT *
FROM MyTable
WHERE (col1, col2, col3) IN (
SELECT col1, col2, col3
FROM MyTable
GROUP BY col1, col2, col3
HAVING count(*) = 1
) AS t
)
WITH uniqe AS (
SELECT *
FROM (
SELECT col1, col2, col3, dateRange
, count(*) OVER (PARTITION BY col1, col2, col3) AS cnt
FROM MyTable
) AS t
WHERE cnt = 1
)
正如Andomar 解释的那样,它影响窗口函数结果的计算方式PARTITION BY
类似于,但与 不同的是,它不影响返回的行数。GROUP BY
GROUP BY
推荐阅读
- php - CS-Cart 用户使用 rest api 登录
- python - 如何在熊猫和日期时间上设置最新日期
- apache-kafka - 当Kafka在同一个请求中发送多个批次时?
- javascript - 如何在表单提交时滚动到第一个 ng-invalid 类
- angular - 通过核心 API 和后台服务从 Angular 轮询
- azure - 如何识别 Cosmos DB RU 消耗的来源?
- android - 如何在Android中获取线程ID
- python-3.x - 使用邻接矩阵的最短路径的 Dijkstra 算法
- python - docker-py:Docker Python sdk container.put_archive 不工作
- angular - 在网络浏览器中按下后退按钮后,角度输入值仍然存在