【问题标题】:How to select rows if unique?如果唯一,如何选择行?
【发布时间】:2019-07-05 15:38:37
【问题描述】:

我正在尝试进行两部分查询并返回一个由分号分隔的列值组成的文本数组。

首先,根据三列的值仅选择唯一的行(即,如果三个值的元组存在不止一次,则它不是唯一的)。在剩余的行中,根据第四列执行另一个过滤器。

这就是我的想法,但也许有更好的解决方案。

我已经尝试了几种不同的方法。我目前的尝试是使用 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 行是唯一的唯一行。

【问题讨论】:

    标签: postgresql


    【解决方案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
    )    
    

    PARTITION BY method:

    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 explainsPARTITION BYGROUP BY 在影响窗口函数的方式上相似 结果是计算的,但与GROUP BY不同,它不影响计算的数量 返回的行。

    【讨论】:

    • 我必须将dateRange col 添加到您的选择语句中,但仅此而已。如果您更新答案,我会将其作为选定答案。非常感谢。 (我必须阅读表分区,因为我不是 100% 确定这里发生了什么)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 2017-02-14
    • 2011-02-28
    • 1970-01-01
    相关资源
    最近更新 更多