他の3つの列の一意の組み合わせを持つ重複行に基づいて、列(列名DEF)に異なる値を持つ行のみを取得したい。
例:以下の例では、最初の2つの行の最初の3列は同じ値ですが、列DEFの値は異なります。したがって、これらの両方の行が出力にリストされます。
ただし、行2と4には最初の3列の一意の組み合わせがありますが、DEF列には同じ値があるため、出力には表示されません。
行5と6は、値が異なる単一行であるため、リストされません。
+----------+-------+--------+--------+
| dept | role1 |role2 |DEF |
+----------+-------+--------+--------+
| a | abc | er | 0 |
| a | abc | er | 1 |
| b | qwer | ty | 0 |
| b | qwer | ty | 0 |
| c | der | ui | 1 |
| d | nerr | io | 0 |
+----------+-------+--------+--------+
output
+----------+------+------+------+
| dept | role1|role2 |DEF |
+----------+------+------+------+
| a | abc | er |0 |
| a | abc | er |1 |
+----------+------+------+------+
列DEFの値を確認することはできますが、目的の結果を得ることはできません。
誰かが私を助けてくれますか?
ほとんどのRDBMSで標準SQLを使用するには、さまざまな方法があります。
SELECT d.dept, d.role1, d.role2, DEF
FROM data d
INNER JOIN (
SELECT dept, role1, role2
FROM data
GROUP BY dept, role1, role2
HAVING COUNT(distinct DEF) > 1
) dup
ON dup.dept = d.dept AND dup.role1 = d.role1 AND dup.role2 = d.role2
;
サブクエリは、複数の異なるDEF
を含むdept/role1/role2
のセットを返します。
SELECT d.dept, d.role1, d.role2, DEF
FROM @data d
WHERE EXISTS (
SELECT 1
FROM @data
WHERE dept = d.dept AND role1 = d.role1 AND role2 = d.role2 AND DEF <> d.DEF
);
サブクエリは0〜n行を返します。少なくとも1つの行が存在する場合、メインテーブルの行が返されます。
CROSS APPLY
の使用:SELECT d.dept, d.role1, d.role2, d.DEF
FROM @data d
CROSS APPLY (
SELECT n=1
FROM @data
WHERE dept = d.dept AND role1 = d.role1 AND role2 = d.role2 AND DEF <> d.DEF
) ca
;
CROSS APPLYは、OracleまたはSQL Serverで動作します。
dept role1 role2 DEF
a abc er 0
a abc er 1