2

次の形式のテーブルがあります。

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

重複が存在するかどうかに基づいて、クエリの結果から特定の行を除外したいと思います。ただし、この場合、重複行の定義はかなり複雑です。

クエリによって返された行(この架空の行をと呼びましょうThisRow)に対応する行がクエリ結果に含まれている場合、 ANDLocと同じ形式である場合は、重複と見なしてクエリ結果から除外する必要があります。ThisRow.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

これが1つの方法です:

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

提供するデータの例では、重複する行に重複するlocがない例はありません。たとえば、行「123-AZ、1」がない場合、プレフィックス行「123、1」は2つの行と競合します。

これがデータの実際の特性である場合は、集計を使用して、自己結合なしで重複を排除できます。

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 に答える