2012-05-18 2 views
7

Я был бы очень признателен, если бы кто-то мог проверить мой SQL-запрос.Mysql Выбор строк с одинаковыми значениями в одном столбце и разными в другом

Для следующего набора данных:

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.

Другими словами, я хотел бы знать MD5 и categoryPK всех записей, в которых два или более разных пользователя (UserPK) назначили одну и ту же категорию (UserPK) в тот же файл (Md5). Меня не интересуют записи, которые один и тот же пользователь присвоил этой категории несколько раз (если другой пользователь не присвоил этому типу той же категории).

Так из приведенных выше данных, я хотел бы быть возвращен только:

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; 

Это похоже на работу, но прежде чем начать использовать он в гневе, я был бы признателен за второе мнение в случае, если я что-то пропустил, или если есть лучший способ сделать это.

Благодаря

+3

Такого рода вопрос может быть более подходящим для [Обзор Code] (http://codereview.stackexchange.com), чем StackOverflow. – eggyal

ответ

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" ? 
+0

Хороший вопрос - я только что проверил одну из своих таблиц, и я нашел еще 10 файлов, используя этот запрос! – user1395659

1

Я не вижу никаких проблем с тем, что вы написали, кроме вы не получаете категорию в вашем списке выбора, который, как представляется, быть в критериях? Я думаю, вы могли бы упростить ее немного и получить категорию из:

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

В качестве альтернативы, вы можете посмотреть на решение этого с объединением, возможно, потребуется провести несколько тестов и использовать EXPLAIN, но иногда присоединяется лучше, чем ГРУППА ПО. В любом случае стоит попробовать увидеть, есть ли какая-либо существенная разница.

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 
+0

+1 для обоих предложений (хотя, если OP фактически означало «* более двух разных пользователей *», как описано в его тексте, они, очевидно, не дадут желаемого результата, но на основании его попытки я согласен, что он, вероятно, имел в виду * по меньшей мере, два..*). Тем не менее, я думаю, что ваш комментарий о том, что нет никаких проблем с тем, что написал OP, ошибочен: см. Мое наблюдение в начале моего ответа. – eggyal

+0

Да, вы правы, я имел в виду по крайней мере два, и я исправил вопрос. – user1395659

Смежные вопросы