我在创建查询时遇到问题,该查询没有从表中获取重复值。不幸的是,全名列的名称和姓氏的顺序不同。
例如:
+----+----------------------+
| 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 |
+----+-----------------------+
我的目标是创建查询,查询的方式类似,例如:为姓名和姓氏以相同顺序选择不同的。
有什么想法吗?
答案 0 :(得分:1)
它需要大量String operations,并且需要使用多个Derived Tables。 可能没有效率。
我们首先将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 |