2

会社のさまざまなシステムで従業員が使用している現在のユーザー名の重複をチェックするために使用されるデータベースを構築しています。以前は、一部の従業員が一部のシステムへの同じユーザー名アクセスを共有していました。各システムの各従業員に固有のユーザー名を設定することが目的であるため、共有アクセスを使用している従業員を特定する必要があります。データベースには、従業員の名前とそれぞれのユーザー名を含む 1 つのテーブルがあります。

例: 表 1

Employee    System1 System2  System3
John Doe    dJohn   Pkls453  xfd801
Jane Doe    dJane   Pkls454  xfd801
James Lee   dJames  Pkls455  fd674
Mark Jones  dMark   Pkls453  xfd752

生成する必要があるのは、John Doe と Jane Doe が System3 で同じアクセスを共有していること、および John Doe と Mark Jones が System2 のアクセスを共有していることを示すレポートです。何かのようなもの:

Employee  System3  System2
John Doe  xfd801
Jane Doe  xfd801
John Doe           Pkls453
Mark Jones         Pkls453

これを取り除く方法はありますか?

前もって感謝します...

4

2 に答える 2

2

よりクリーンなソリューションがあると確信していますが、これにより、探しているものが指定した形式で返されるはずです。

SELECT Employee, System1, NULL AS System2, NULL AS System3
FROM your_table T1
WHERE EXISTS(SELECT * FROM your_table T2
         WHERE T1.System1 = T2.System1
         AND T1.Employee <> T2.Employee)
UNION
SELECT Employee, NULL AS System1, System2, NULL AS System3
FROM your_table T1
WHERE EXISTS(SELECT * FROM your_table T2
         WHERE T1.System2 = T2.System2
         AND T1.Employee <> T2.Employee)
UNION
SELECT Employee, NULL AS System1, NULL AS System2, System3
FROM your_table T1
WHERE EXISTS(SELECT * FROM your_table T2
         WHERE T1.System3 = T2.System3
         AND T1.Employee <> T2.Employee)
ORDER BY System1, System2, System3
于 2012-08-14T22:10:44.550 に答える
2

システムがウィンドウ関数をサポートしている場合、これは機能します。

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 でテスト済み。

于 2012-08-14T22:14:31.023 に答える