【问题标题】:find users whose non-uid attributes are identical查找非uid属性相同的用户
【发布时间】:2017-02-25 22:57:11
【问题描述】:

我有桌子

CREATE TABLE Permission (uid char(32), pid char(32), term char(32),
PRIMARY KEY (uid, pid, term))

包含诸如

之类的值
uid    pid    term
0001   1001   3                            
0001   1002   3                            
0001   1002   4                            
0002   1001   3                            
0002   1002   3                            
0002   1002   4                            
0003   1001   3                            
0003   1002   4                            
0003   1002   5

我想返回所有具有相同 pid 和 term 值的用户的 uid,在这个例子中我想要 0001 和 0002,但我不知道如何比较每个 uid 的 pid 和 term 值其他 uid 的 pid 和 term 值。我能得到的最接近的是确定每个用户是否有重复的 pid。

SELECT uid
FROM Permission
GROUP BY uid, pid
HAVING COUNT (*) > 1

我什至不确定这与我要执行的测试有关。和

SELECT uid
FROM (SELECT P1.uid, P1.pid
      FROM Permission P1
      WHERE EXISTS (SELECT P2.pid
                    FROM Permission P2
                    WHERE P1.pid = P2.pid)) P
GROUP BY P.uid
HAVING COUNT (P.pid) = (SELECT COUNT (P3.pid)
                        FROM Permission P3
                        WHERE P3.uid = P.uid)

我认为应该可行,但我显然错了,因为它只返回所有 uid =)

【问题讨论】:

    标签: sql sql-server database


    【解决方案1】:

    您可以通过自联接和聚合来做到这一点:

    with p as (
          select p.*, count(*) over (partition by uid) as cnt
          from permissions p
         )
    select p1.uid, p2.uid
    from p p1 join
         p p2
         on p1.pid = p2.pid and
            p1.term = p2.term and
            p1.cnt = p2.cnt and
            p1.uid < p2.uid
    group by p1.uid, p2.uid, p1.cnt
    having count(*) = p1.cnt;
    

    【讨论】:

    • 这不是强制性的,这个解决方案可以满足它的需要,但是如果有超过 2 个相同的情况,例如如果 1、2 和 4 都匹配 (1、2 ) (1, 4) (2,4)。将所有这些组合成一个解决方案(1、2、4)的快速方法是什么,无论是元组、字符串还是其他?
    • 您可能想将其作为另一个问题提出。答案可能看起来完全不同。
    • 好的,与其说是要求,不如说是好奇,如果我需要继续,我会听取你的建议,谢谢。
    【解决方案2】:

    按所有三个列分组

    SELECT uid, pid, term
    FROM PERMISSION
    GROUP BY uid, pid, term
    HAVING COUNT(*) > 1
    

    如果您只需要一列,您可以从中进行选择

    SELECT DISTINCT uid 
    FROM (
      SELECT uid, pid, term
      FROM PERMISSION
      GROUP BY uid, pid, term
      HAVING COUNT(*) > 1
    ) t
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多