MySql: выберите Distinct для слов в другом порядке - PullRequest
0 голосов
/ 10 ноября 2018

У меня проблема с созданием запроса, который не получает повторяющихся значений из моей таблицы. К сожалению, Полное имя столбец имеет имя и фамилию в другом порядке.

Например:

+----+----------------------+
| ID | Full Name            |
+----+----------------------+
| 1  | Marshall Wilson      |
| 2  | Wilson Marshall      |
| 3  | Lori Hill            |
| 4  | Hill Lori            |
| 5  | Casey Dean Davidson  |
| 6  | Davidson Casey Dean  |
+----+----------------------+

Я бы хотел получить такой результат:

+----+-----------------------+
| ID | Full Name             |
+----+-----------------------+
| 1  | Marshall Wilson       |
| 3  | Lori Hill             |
| 5  | Casey Dean Davidson   |
+----+-----------------------+

Моя цель - создать запрос, который будет аналогичным образом, например: выбрать отличные для Имени и Фамилии в том же порядке.

Есть мысли?

1 Ответ

0 голосов
/ 10 ноября 2018

Требуется множество Строковых операций и использование нескольких Производных таблиц . Это может быть неэффективным .

Сначала токенизируем FullName в несколько слов, из которых он сделан. Для этого мы используем таблицу генератора чисел gen. В этом случае я предположил, что максимальное количество подстрок равно 3. Вы можете легко расширить его, добавив больше Select, например, SELECT 4 UNION ALL .. и т. Д.

Мы используем Substring_Index() с функцией Replace(), чтобы получить подстроку, используя один символ пробела (' ') в качестве разделителя. Trim() используется для удаления оставшихся начальных / конечных пробелов.

Теперь хитрость заключается в том, чтобы использовать этот набор результатов в качестве производной таблицы и сделать Group_Concat() для слов таким образом, чтобы они сортировались в порядке возрастания. Таким образом, даже дубликаты имен (но подстроки в другом порядке) получат аналогичное значение words_sorted. В конце концов нам просто нужно Group By на words_sorted, чтобы отсеять дубликаты.


Запрос № 1

SELECT 
  MIN(dt2.ID) AS ID, 
  MIN(dt2.FullName) AS FullName 
FROM 
(
SELECT 
  dt1.ID, 
  dt1.FullName, 
  GROUP_CONCAT(IF(word = '', NULL, word) ORDER BY word ASC) words_sorted 
FROM 
(
SELECT e.ID, 
       e.FullName, 
       TRIM(REPLACE(
         SUBSTRING_INDEX(e.FullName, ' ', gen.idx), 
         SUBSTRING_INDEX(e.FullName, ' ', gen.idx-1),
         '')) AS word 
FROM employees AS e
CROSS JOIN (SELECT 1 AS idx UNION ALL 
            SELECT 2 UNION ALL 
            SELECT 3) AS gen -- You can add more numbers if more than 3 substrings
) AS dt1 
GROUP BY dt1.ID, dt1.FullName
) AS dt2
GROUP BY dt2.words_sorted
ORDER BY ID;

| ID  | FullName            |
| --- | ------------------- |
| 1   | Marshall Wilson     |
| 3   | Hill Lori           |
| 5   | Casey Dean Davidson |

Просмотр на БД Fiddle

...