【问题标题】:Select rows with the same set regardless of the order无论顺序如何,都选择具有相同集合的行
【发布时间】:2019-10-29 01:46:33
【问题描述】:

给定:

id | a | b | c
---------------
1  | 3 | 8 | 7
2  | 4 | 5 | 6
3  | 0 | 8 | 1
4  | 2 | 4 | 6
5  | 6 | 5 | 4
6  | 9 | 5 | 2
7  | 0 | 1 | 8

就像在彩票中一样,我想选择所有具有相同组合的行,而不管顺序如何。预期的选择应该给我

id | a | b | c
---------------
2  | 4 | 5 | 6
5  | 6 | 5 | 4
3  | 0 | 8 | 1
7  | 0 | 1 | 8

我尝试 SELF JOINing 表本身,不确定这是否是正确的方法。这是postgres

【问题讨论】:

  • id=5 相同的数字为什么要选择id=2?还是随便选一个?以及为什么您选择 id 3 和 7 都具有相同的数字
  • 这是一个现有的数据库,我有一个业务需求来获得相同的组合
  • 他们正在选择重复项。 2/5 是重复的组合,因此它们都被选中;和 3/7 一样。
  • 你的 rdbms 是什么? mysql?后勤? sql服务器?

标签: sql postgresql


【解决方案1】:

您可以使用exists 进行过滤:

select t.*
from mytable t
where exists (
    select 1
    from mytable t1
    where 
        t1.id <> t.id
        and t1.a in (t.a, t.b, t.c)
        and t1.b in (t.a, t.b, t.c)
        and t1.c in (t.a, t.b, t.c)
)

Demo on DB Fiddle

编号 |一个 |乙 | C -: | -: | -: | -: 5 | 6 | 5 | 4 7 | 0 | 1 | 8 2 | 4 | 5 | 6 3 | 0 | 8 | 1

【讨论】:

  • 我认为你想要 EXISTS 看起来他想要找到重复项
  • T1.a T1.b 和 T1.c 不是 T1.id
  • @JuanCarlosOropeza:是的,你是对的,我编辑了我的答案。
  • 你想要两条记录,所以 t1.id t.id
  • @letthefireflieslive 。 . .这将识别 (1, 2, 2) 和 (1, 1, 2) 相同。您的问题没有指定如何处理重复项,但我认为这不是问题的正确答案:“我想选择所有具有相同组合的行,而不管顺序如何。”
【解决方案2】:

Postgres 有一些功能可以很好地完成这项工作。特别是,您可以对数组中的列进行排序,然后计算重复的数量:

select t.*
from (select t.*, count(*) over (partition by ar) as cnt
      from (select t.*,
                   (select array_agg(el order by el)
                    from (values (t.a), (t.b), (t.c)) v(el)
                   ) as ar
            from mytable t 
           ) t
     ) t
where cnt > 1
order by ar;

非常重要:这适用于 exact 匹配,即使是重复的。所以,(1, 1, 2) 不匹配 (1, 2, 2)。

【讨论】:

    【解决方案3】:

    我很好奇如何匹配你的期望输出将匹配放在一起

    使用 GMB 答案,您可以添加排序字段

    SQL DEMO

    select t.*, LEAST (t.id, (select t1.id
                              from mytable t1
                              where t1.id <> t.id
                                and t1.a in (t.a, t.b, t.c)
                                and t1.b in (t.a, t.b, t.c)
                                and t1.c in (t.a, t.b, t.c)
                             )
                       ) as sortfield
    from mytable t
    where exists (
        select 1
        from mytable t1
        where 
            t1.id <> t.id
            and t1.a in (t.a, t.b, t.c)
            and t1.b in (t.a, t.b, t.c)
            and t1.c in (t.a, t.b, t.c)
    )
    ORDER BY sortfield
    

    输出

    id  a   b   c   sortfield
    5   6   5   4   2
    2   4   5   6   2
    7   0   1   8   3
    3   0   8   1   3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-31
      • 2013-03-26
      • 2017-10-10
      • 2018-09-08
      • 2021-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多