MySQL: поиск повторяющихся имен в моей таблице пользователей - PullRequest
4 голосов
/ 04 апреля 2011

Я хочу найти всех пользователей, чье имя появляется хотя бы дважды в моей таблице пользователей. 'email' - это уникальное поле, но комбинация 'firstName' и 'lastName' не обязательно является уникальной.

Пока что я предложил следующий запрос, который очень медленный, и я даже не уверен, что он правильный. Пожалуйста, дайте мне знать лучший способ переписать это.

SELECT CONCAT(u2.firstName, u2.lastName) AS fullName
FROM cpnc_User u2
WHERE CONCAT(u2.firstName, u2.lastName) IN (

SELECT CONCAT(u2.firstName, u2.lastName) AS fullNm
FROM cpnc_User u1
GROUP BY fullNm
HAVING COUNT(*) > 1

)

Также обратите внимание, что приведенное выше возвращает список имен, которые появляются по крайней мере дважды (я так думаю, в любом случае), но мне действительно нужен полный список всех полей 'id' пользователя для этих имен. Таким образом, каждое имя, поскольку оно встречается как минимум дважды, будет связано как минимум с двумя полями идентификатора первичного ключа.

Спасибо за любую помощь! Ионы

Ответы [ 5 ]

7 голосов
/ 04 апреля 2011
SELECT u.*
FROM cpnc_User u JOIN
(
    SELECT firstName, lastName
    FROM cpnc_User
    GROUP BY firstName, lastName
    HAVING COUNT(*) > 1
) X on X.firstName = u.firstName AND x.lastName = u.lastName
ORDER BY u.firstName, u.lastName

Нет необходимости составлять объединенное поле, просто используйте 2 поля отдельно

3 голосов
/ 04 апреля 2011
SELECT u.id, u.firstName, u.lastName
FROM cpnc_User u, (
  SELECT uc.firstName, uc.lastName 
  FROM cpnc_User uc 
  GROUP BY uc.firstName, uc.lastName 
  HAVING count(*) > 1
) u2
WHERE (
  u.firstName = u2.firstName
  AND u.lastName = u2.lastName
)
2 голосов
/ 04 апреля 2011

Для эксперимента я создал простую таблицу с двумя столбцами: идентификатором пользователя и именем. Я вставил кучу записей, включая некоторые дубликаты. Затем запустил этот запрос:

SELECT
count(id) AS count,
group_concat(id) as IDs
FROM
test
GROUP BY
`name`
ORDER BY
count DESC

Это должно дать вам такие результаты:

+-------+----------+
| count | IDs      |
+-------+----------+
|     4 | 7,15,4,1 | 
|     2 | 2,8      | 
|     2 | 6,13     | 
|     2 | 14,9     | 
|     1 | 11       | 
|     1 | 10       | 
|     1 | 3        | 
|     1 | 5        | 
|     1 | 17       | 
|     1 | 12       | 
|     1 | 16       | 
+-------+----------+

Вам нужно будет отфильтровать последующие результаты, используя что-то еще.

2 голосов
/ 04 апреля 2011
SELECT u.id
     , CONCAT(u.firstName, ' ', u.lastName) AS fullname
FROM cpnc_User u
  JOIN 
  ( SELECT min(id) AS minid
         , firstName
         , lastName
    FROM cpnc_User 
    GROUP BY firstName, lastName
    HAVING COUNT(*) > 1
  ) AS grp
  ON u.firstName = grp.firstName
    AND u.lastName = grp.lastName
  ORDER BY grp.minid
         , u.id 

ORDER BY grp.minid гарантирует, что пользователи с одинаковыми именем и фамилией будут сгруппированы в выходных данных.

1 голос
/ 04 апреля 2011

ОК, вы делаете конкатенацию, а затем сравниваете ее, что по сути означает, что БД придется что-то делать с каждой строкой базы данных.

Как насчет немного другойподход, вы держите фамилию и имя отдельно.Поэтому сначала выберите все те случаи, когда фамилия появляется> 1 раз в вашей базе данных.Теперь это резко сократило вашу популяцию.

Теперь вы можете сделать сравнение по имени, чтобы узнать, где совпадения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...