Mysql选择一列中具有相同值而另一列中具有不同值的行

时间:2012-05-18 09:28:30

标签: mysql select count distinct

如果有人可以验证我的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)为同一个文件(Md5)分配了相同类别(UserPK)的所有记录的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;

它似乎有效,但在我开始使用它之前,我会欣赏第二种意见,以防我错过了某些内容或者是否有更好的方法。

由于

2 个答案:

答案 0 :(得分:11)

我认为你的代码不会给你你所追求的东西;如果多个用户为一个文件分配了多个类别,某些类别重叠,会发生什么?然后是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" ?

答案 1 :(得分: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