我的表格格式为:
Id | Loc |
-------|-----|
789-A | 4 |
123 | 1 |
123-BZ | 1 |
123-CG | 2 |
456 | 2 |
456 | 3 |
789 | 4 |
我想根据是否存在重复,从查询结果中排除某些行。但是,在这种情况下,重复行的定义非常复杂:
如果查询返回的任何行(让我们将此假设行称为ThisRow
),则查询结果中还包含对应的行 其中{ {1}}与Loc
相同而ThisRow.Loc
的格式为Id
,则<ThisRow.Id>-<an alphanumeric suffix>
应视为重复,并从查询结果中排除。
例如,使用上表,ThisRow
应返回以下结果集:
SELECT * FROM table
我理解如何编写匹配条件的字符串:
Id | Loc |
-------|-----|
789-A | 4 |
123-BZ | 1 |
123-CG | 2 |
456 | 2 |
456 | 3 |
和ThisRow.Id REGEXP '^PossibleDuplicateRow.Id-[A-Za-z0-9]*'
:
Loc
我不明白的是如何将这些条件形成为(自引用?)查询。
答案 0 :(得分:3)
这是一种方式:
SELECT *
FROM myTable t1
WHERE NOT EXISTS
(
SELECT 1
FROM myTable t2
WHERE t2.Loc = t1.Loc
AND t2.Id LIKE CONCAT(t1.Id, '-%')
)
或者,使用反连接的相同查询(应该更快一点):
SELECT *
FROM myTable t1
LEFT OUTER JOIN myTable t2
ON t2.Loc = t1.Loc
AND t2.Id LIKE CONCAT(t1.Id, '-%')
WHERE t2.Id IS NULL
答案 1 :(得分:0)
在您提供的示例数据中,没有重复的位置不在重复行上的示例。例如,您没有“123-AZ,1”行,其中前缀行“123,1”将与两行冲突。
如果这是数据的真实特征,那么您可以通过使用聚合来消除没有自联接的重复:
select max(id), loc
from t
group by (case when locate(id, '-') = 0 then id
else left(id, locate(id, '-') - 1)
end), loc
我提供这个是因为聚合应该比非等值连接快得多。