7

如果有人可以验证我的 SQL 查询,我将不胜感激。

对于以下数据集:

MD5      UserPK      CategoryPK    
ADCDE    1           7  
ADCDE    1           4  
ADCDE    1           7  
dffrf    1           7  
dffrf    2           7  
dffrf    2           6 
dffrf    1           1 

我想选择 MD5 和 CategoryPK,其中存在两行或多行具有相同的 MD5 值、相同的 CatgegoryPK 和两个或更多不同的 UserPK 值。

换句话说,我想知道两个或多个不同用户 (UserPK) 将相同类别 (UserPK) 分配给同一文件 (Md5) 的所有记录的 MD5 和 categoryPK。我对同一用户多次分配类别的记录不感兴趣(除非不同的用户也为该文件分配了相同的类别)。

所以从上面的数据来看,我只想返回:

md5    CategoryPK
dffrf  7

我写的查询是:

SELECT md5, 
       count(md5), 
       count(distinct categorypk) as cntcat, 
       count(distinct userpk) as cntpk
FROM Hash
       group by md5 having count(md5) > 1 
                           and cntpk > 1
                           and cntcat = 1;

它似乎有效,但在我开始愤怒地使用它之前,如果我错过了什么或者有更好的方法,我会很感激第二个意见。

谢谢

4

2 回答 2

13

我不认为你的代码会给你你所追求的;如果一个文件被多个用户分配了多个类别,并且某些类别重叠,会发生什么情况?然后,即使文件确实已被多个用户以相同的方式分类cntcat != 1,您的子句也将无法匹配。HAVING

我会改为使用自加入:

SELECT   a.MD5, a.CategoryPK
FROM     Hash a
  JOIN   Hash b
      ON a.MD5 = b.MD5
     AND a.UserPK <> b.UserPK
     AND a.CategoryPK = b.CategoryPK
GROUP BY a.MD5, a.CategoryPK
HAVING   COUNT(DISTINCT a.UserPK) > 2  -- you said "more than 2" ?
于 2012-05-18T09:37:47.593 回答
1

除了您没有在您的选择列表中获得似乎在标准中的类别之外,我看不出您所写的内容有任何问题?我认为您可以稍微简化一下并找出类别:

SELECT  MD5, CategoryPK
FROM    Hash
GROUP BY MD5, CategoryPK
HAVING MIN(UserPK) <> MAX(UserPK)

或者,您可以通过连接来解决这个问题,您可能需要运行一些测试并使用 EXPLAIN,但有时连接的性能比 GROUP BY 更好。无论如何,值得尝试看看您是否看到任何显着差异。

SELECT  DISTINCT t1.MDF, t2.CategoryPK
FROM    Hash T1
        INNER JOIN Hash T2
            ON T1.MD5 = T2.MD5
            AND T1.CategoryPK = T2.CategoryPK
            AND T1.UserPK < T2.UserPK
于 2012-05-18T09:37:22.980 回答