我正在尝试进行两部分查询,并返回以分号分隔的列值的文本数组。
首先,仅根据三列的值选择唯一的行(即,如果三个值的元组存在多次,则它不是唯一的)。在其余的行中,根据第四列执行另一个过滤器。
这就是我的想法,但是也许有更好的解决方案。
我已经尝试了几种不同的方法。我目前的尝试是使用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) ...
似乎从我不认为“唯一”的其他行中至少选择了一行。
请清楚,这是一个示例表:
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行是唯一的唯一行。
答案 0 :(得分:1)
从本质上讲,问题归结为根据聚合或窗口函数的值选择行。
因此solutions here是适用的,除了在我们的情况下,我们希望count(*)
等于1。
因此,我们可以使用WHERE IN
method:
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 explains一样,PARTITION BY
与GROUP BY
的相似之处在于它影响窗口函数的方式
计算结果,但与GROUP BY
不同,它不会影响
返回的行。