Найти строки с одинаковыми / похожими значениями столбцов MySQL - PullRequest
1 голос
/ 08 февраля 2011

Я хочу выбрать из следующей таблицы все строки, которые имеют значения в столбце fname, аналогичные первым в их порядке. IOW из этой таблицы я хочу получить строки с идентификаторами 2,5 и 7 (потому что « anna » идет после « anna », а « michaela » « michaal » после « michael »).

+----+------------+----------+
| id | fname      | lname    |
+----+------------+----------+
|  1 | anna       | milski   |
|  2 |  anna      | nguyen   |
|  3 | michael    | michaels |
|  4 | james      | bond     |
|  5 | michaela   | king     |
|  6 | bruce      | smart    |
|  7 | michaal    | hardy    |
+----+------------+----------+

То, что я имею до сих пор, это:

select *, count(fname) cnt 
from users group by soundex(fname) 
having count(soundex(fname)) > 1;

но так как я группирую это, результат будет

+----+----------+----------+-----+
| id | fname    | lname    | cnt |
+----+----------+----------+-----+
|  1 | anna     | milski   |   2 |
|  3 | michael  | michaels |   3 |
+----+----------+----------+-----+

То, что я хочу получить, это:

+----+----------+----------+-----+
| id | fname    | lname    | cnt |
+----+----------+----------+-----+
|  2 |  anna    | nyugen   |   2 |
|  5 | michaela | king     |   3 |
|  7 | michaal  | hardy    |   3 |
+----+----------+----------+-----+

Что я должен изменить в запросе? Я пытался удалить "group by", но это меняет результаты (я могу ошибаться, не проверял это подробно).

Ответы [ 2 ]

2 голосов
/ 09 февраля 2011

Я перечитал ваш первоначальный вопрос и нашел следующее решение:

SELECT *
FROM   users
WHERE  id IN
       (SELECT id
       FROM    users t4
               INNER JOIN
                       (SELECT  soundex(fname) AS snd,
                                COUNT(*)       AS cnt
                       FROM     users          AS t5
                       GROUP BY snd
                       HAVING   cnt > 1
                       )
                       AS t6
               ON      soundex(t4.fname)=snd
       )
AND    id NOT IN
       (SELECT  MIN(t2.id) AS wanted
       FROM     users t2
                INNER JOIN
                         (SELECT  soundex(fname) AS snd,
                                  COUNT(*)       AS cnt
                         FROM     users          AS t1
                         GROUP BY snd
                         HAVING   cnt > 1
                         )
                         AS t3
                ON       soundex(t2.fname)=snd
       GROUP BY snd
       );

Это немного сложно, но работает и доставляет именно то, что вы просили:)

0 голосов
/ 08 февраля 2011

Вы, похоже, получаете то, что просите - SOUNDEX(fname) сделает хеши Soundex только от имени, а не от целой строки. Несколько вариантов, которые вы можете исследовать:

SELECT *, COUNT(SOUNDEX(CONCAT(fname, lname))) AS cnt
GROUP BY SOUNDEX(CONCAT(fname, lname))
HAVING cnt > 1;

или

SELECT *, COUNT(SOUNDEX(fname)) AS cnt1, COUNT(SOUNDEX(lname)) AS cnt2
GROUP BY SOUNDEX(fname), SOUNDEX(lname)
HAVING cnt1 > 1 OR cnt2 > 1

Это зависит от того, чего вы хотите достичь: количество похожих имен, фамилий или некоторый синтаксис обоих.

...