2

我有一张表格,格式如下:

Id     | Loc |
-------|-----|
789-A  | 4   |
123    | 1   |
123-BZ | 1   |
123-CG | 2   |
456    | 2   |
456    | 3   |
789    | 4   |

我想根据是否存在重复从查询结果中排除某些行。但是,在这种情况下,重复行的定义非常复杂:

如果查询返回的任何行(让我们将此假设行称为)在查询结果中也包含与AND形式相同ThisRow的对应行,则应将其视为重复并从查询结果中排除。LocThisRow.LocId<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

ThisRow.Loc = PossibleDuplicateRow.Loc

我不明白的是如何将这些条件形成一个(自引用?)查询。

4

2 回答 2

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, '-%')
)

SQL 小提琴示例

或者,使用反连接的相同查询(应该快一点):

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

SQL 小提琴示例

于 2012-11-10T15:57:41.657 回答
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

我提供这个是因为聚合应该比非等值连接快得多。

于 2012-11-10T16:30:00.983 回答