【问题标题】:select first distinct values from two fields从两个字段中选择第一个不同的值
【发布时间】:2016-11-23 23:36:26
【问题描述】:

这看起来非常简单,但我只是没有把它放在一起。说我有价值观

 a | b
---+---
 1 | 10
 1 | 20
 2 | 10
 2 | 20

如何从该表中进行选择,以便在表中获取这些值:

 a | b
---+---
 1 | 10
 2 | 20

同样适用于:

 a | b
---+---
 1 | 10
 1 | 20
 1 | 30
 2 | 10
 2 | 20
 2 | 30
 3 | 10
 3 | 20
 3 | 30

得到

 a | b
---+---
 1 | 10
 2 | 20
 3 | 30

我尝试了 distinct on 和 order by 的不同组合,但这些都行不通,因为它确实需要在 a 和 b 上都不同。也许是一个窗口函数......?如果重要,请使用 postgres。

【问题讨论】:

  • @klin b 是 b 列中的第一个唯一值。所以如果 1 | 10 已存在 2 | 10 无效,必须为 2 | 20
  • 使用ctrl-K或在行首添加4个空格以格式化为code
  • 是否保证每个a 恰好出现n次?
  • 在我的数据集中,我相信是这样。我的数据集真正的复杂性是这个操作应该只发生在重复项上。所以如果集合是 {1,10}, {1,20}, {2, 10}, {2,20}, {3,999} 结果应该是 {1,10}, {2,20}, {3,999} .基本上是非笛卡尔积重复。也许这超出了我所问的范围......

标签: sql database postgresql select


【解决方案1】:

我不确定distinct 在这里是否正确,但如果我理解正确,您有一组 a 和 b 的值,以及每个组合的行,并且您希望将第一个 a 与第一个 b 匹配, 第二个 a 和第二个 b 等等。一种方法是使用窗口函数 rank 两列,然后只查询具有等于等级的行:

SELECT a, b
FROM   (SELECT a, RANK() OVER (ORDER BY a) AS rank_a,
               b, RANK() OVER (ORDER BY b) AS rank_b
        FROM   myable) t
WHERE  rank_a = rank_b

【讨论】:

  • 如果组中的值数量不相等,这将无法可靠地工作。
  • 是的,我很难找到正确的术语,因此无法通过 google-fu 甚至准确地描述问题。只是为了好玩,你会怎么称呼这种操作?逆笛卡尔积? @vkp 如何处理不相等数量的值?
  • 我要去,是的,这就是我问的。问题的附录(附录?meh)涉及仅在重复的情况下执行此操作,可以通过将起点用作子查询并加入“不在哪里”来很容易地解决,过于模糊。谢谢!
  • @low_ghost 坦率地说,我不知道如何称呼这种模式,抱歉。
【解决方案2】:

这是对附录问题的回答,似乎并不能真正归类为评论。使用@Mureinik 的答案作为基础。我确信有一种更简洁的 sql 方法,但对于快速的第一次尝试:

WITH duplicate_a 
     AS (SELECT a 
         FROM   temp_table_1 
         GROUP  BY a 
         HAVING Count(1) > 1), 
     unduplicated 
     AS (SELECT a, 
                b 
         FROM   (SELECT a, 
                        Rank() OVER ( ORDER BY a) AS rank_a, 
                        b, 
                        Rank() OVER ( ORDER BY b) AS rank_b 
                 FROM   temp_table_1) t 
         WHERE  rank_a = rank_b 
           AND a IN (SELECT * 
                     FROM   duplicate_a)) SELECT * 
FROM   unduplicated 
UNION 
SELECT * 
FROM   temp_table_1 
WHERE  a NOT IN (SELECT * 
                 FROM   duplicate_a); 

【讨论】:

  • @JuanCarlosOropeza 我完全支持风格标准化和 linting 等,但这看起来像是一首前卫的诗。 :)
  • 顺便说一句,我不明白附录。这看起来很无用,但是如果这对你有用,那就去吧
猜你喜欢
  • 1970-01-01
  • 2017-09-05
  • 1970-01-01
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多