システムがウィンドウ関数をサポートしている場合、これは機能します。
SELECT employee, system1, system2, system3
FROM (
SELECT employee
,system1
,cast(NULL AS text) AS system2
,cast(NULL AS text) AS system3
,count(*) OVER (PARTITION BY system1) AS ct
FROM tbl1
UNION ALL
SELECT employee
,NULL -- cast and column name only needed in first SELECT in Postgres
,system2
,NULL
,count(*) OVER (PARTITION BY system2) AS ct
FROM tbl1
UNION ALL
SELECT employee
,NULL
,NULL
,system3
,count(*) OVER (PARTITION BY system3) AS ct
FROM tbl1
) x
WHERE ct > 1
ORDER BY system1, system2, system3;
または、おそらくもっと高速です。
複数のシステムを共有している "John Doe" は、すべての共有システムで次のクエリに (最初のクエリとは対照的に) 1 回しかリストされないことに注意してください。非共有システムは に設定されていNULL
ます。
SELECT employee
,CASE WHEN ct1 > 1 THEN system1 ELSE NULL END AS system1
,CASE WHEN ct2 > 1 THEN system2 ELSE NULL END AS system2
,CASE WHEN ct3 > 1 THEN system3 ELSE NULL END AS system3
FROM (
SELECT employee, system1, system2, system3
,count(*) OVER (PARTITION BY system1) AS ct1
,count(*) OVER (PARTITION BY system2) AS ct2
,count(*) OVER (PARTITION BY system3) AS ct3
FROM tbl1
) x
WHERE ct1 > 1 OR ct2 > 1 OR ct3 > 1
ORDER BY system1, system2, system3; -- depends on what you want
または、匿名システムが共通テーブル式をサポートしている場合:
WITH x AS (
SELECT employee, system1, system2, system3
,count(*) OVER (PARTITION BY system1) AS ct1
,count(*) OVER (PARTITION BY system2) AS ct2
,count(*) OVER (PARTITION BY system3) AS ct3
FROM tbl1
)
SELECT employee
,CASE WHEN ct1 > 1 THEN system1 ELSE NULL END AS system1
,CASE WHEN ct2 > 1 THEN system2 ELSE NULL END AS system2
,CASE WHEN ct3 > 1 THEN system3 ELSE NULL END AS system3
FROM x
WHERE ct1 > 1 OR ct2 > 1 OR ct3 > 1
ORDER BY system1, system2, system3; -- depends
CTE もウィンドウ関数もない場合:
(MySQL を含むすべての主要な RDBMS で動作するはずです。)
SELECT t.employee, s1.system1, s2.system2, s3.system3
FROM tbl1 t
LEFT JOIN (SELECT system1 FROM tbl1 GROUP BY 1 HAVING count(*) > 1) s1
ON t.system1 = s1.system1
LEFT JOIN (SELECT system2 FROM tbl1 GROUP BY 1 HAVING count(*) > 1) s2
ON t.system2 = s2.system2
LEFT JOIN (SELECT system3 FROM tbl1 GROUP BY 1 HAVING count(*) > 1) s3
ON t.system3 = s3.system3
WHERE s1.system1 IS NOT NULL
OR s2.system2 IS NOT NULL
OR s3.system3 IS NOT NULL
ORDER BY s1.system1, s2.system2, s3.system3; -- depends
PostgreSQL 9.1.4 でテスト済み。