MySql:为不同顺序的单词选择Distinct

时间:2018-11-10 18:09:27

标签: mysql select distinct

我在创建查询时遇到问题,该查询没有从表中获取重复值。不幸的是,全名列的名称和姓氏的顺序不同。

例如:

+----+----------------------+
| 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 :(得分:1)

它需要大量String operations,并且需要使用多个Derived Tables可能没有效率

我们首先将FullName 令牌化成多个单词。为此,我们使用数字生成器表gen。在这种情况下,我假设子字符串的最大数量为3。您可以通过添加更多的Select(例如SELECT 4 UNION ALL ..等)轻松地进一步扩展它。

我们将Substring_Index()Replace()函数配合使用,以单个空格字符(' ')作为分隔符来获取子字符串。 Trim()用于删除剩余的前导/尾随空格。

现在,诀窍是使用此结果集作为派生表,并对单词进行Group_Concat(),以使它们按升序排序。这样,即使重复的名称(但子字符串的顺序不同)也将获得相似的words_sorted值。最终,我们只需要在Group Bywords_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 |

View on DB Fiddle