2

データベース内のすべての顧客のリストを表示する 7 つのビューがあります。

例えば。

  • ビュー1
  • ビュー2
  • ビュー3
  • ビュー4
  • ビュー5
  • ビュー6
  • ビュー7

現在、各ビューには、これらのどのビューでも同じ顧客が含まれる可能性があります。

これは、現在 UNION を使用してすべてを 1 つの結果セットにまとめる例です:-

SELECT
CustomerId,
Account,
Name,
Balance,
'View1' AS [View 1 List]
FROM View1
UNION
SELECT
CustomerId,
Account,
Name,
Balance,
'View2' AS [View 2 List]
FROM View2
UNION
SELECT
CustomerId,
Account,
Name,
Balance,
'View3' AS [View 3 List]
FROM View3
UNION
SELECT
CustomerId,
Account,
Name,
Balance,
'View4' AS [View 4 List]
FROM View4
UNION
SELECT
CustomerId,
Account,
Name,
Balance,
'View5' AS [View 5 List]
FROM View5
UNION
SELECT
CustomerId,
Account,
Name,
Balance,
'View6' AS [View 6 List]
FROM View6
UNION
SELECT
CustomerId,
Account,
Name,
Balance,
'View7' AS [View 7 List]
FROM View7

このクエリには 2 つの問題があります。

1.最初のビューにある顧客を残りのビューに表示されないように除外し、そこから先に進みたい。したがって、ビュー 2 の顧客には、ビュー 1 の顧客は含まれません。ビュー 1 と 2 に顧客が既に存在する場合、ビュー 3 には顧客が含まれません。ビュー 4 には、顧客が既に存在する場合、顧客は含まれません。ビュー 1、2、3 など: これは 7 番目のビューまで続きます (ビュー 7 では、ビュー 1、2、3、4、5、および 6 で既に報告されている顧客はありません)。

2.この現在のクエリは、最後に「View 1 List」というタイトルの列を生成し、顧客がどのリストにいるかを識別します。

私が探しているのは、関連するビューを識別する各ビューの列を持つ方法です。値は X か何かにすることができます。

これが可能かどうかはわかりませんが、UNION ステートメントを使用して実行できないことはわかっています。

4

2 に答える 2

2

UNION実際にはデフォルトで重複が削除されるため、ビュー 2 の顧客がすべての列でビュー 1 の顧客と一致する場合は、何もする必要はありません。

更新: @Diego が以下で指摘したように、ビューに 1 つまたは複数の列を提供すると重複がなくなるため、それに対する私の元のソリューションではこの利点がなくなります。1 つの解決策はUNION、CTE として最初の操作UNIONを行い、重複を削除するために使用してから、重複が発生しているビュー把握することです。

WITH UnionCTE AS
(
  SELECT
  CustomerId,
  Account,
  Name,
  Balance
  FROM View1

  UNION

  SELECT
  CustomerId,
  Account,
  Name,
  Balance
  From View2

  UNION
  ...
)
SELECT UnionCTE.*,
  CASE
    WHEN EXISTS (SELECT * FROM View1 WHERE CustomerId = UnionCTE.CustomerID) THEN 'View1'
    WHEN EXISTS (SELECT * FROM View2 WHERE CustomerId = UnionCTE.CustomerID) THEN 'View2'
    WHEN EXISTS (SELECT * FROM View3 WHERE CustomerId = UnionCTE.CustomerID) THEN 'View3'
    WHEN EXISTS (SELECT * FROM View4 WHERE CustomerId = UnionCTE.CustomerID) THEN 'View4'
    WHEN EXISTS (SELECT * FROM View5 WHERE CustomerId = UnionCTE.CustomerID) THEN 'View5'
    WHEN EXISTS (SELECT * FROM View6 WHERE CustomerId = UnionCTE.CustomerID) THEN 'View6'
    WHEN EXISTS (SELECT * FROM View7 WHERE CustomerId = UnionCTE.CustomerID) THEN 'View7'
  END AS [ViewNumber]
FROM UnionCTE

上記は、データのソースを示す単一の列を作成します。ビューごとに個別の列が必要な場合は、CTE の後に次を使用できます。

SELECT UnionCTE.*,
  CASE
    WHEN EXISTS (SELECT * FROM View1 WHERE CustomerId = UnionCTE.CustomerID) THEN 'X' 
    END AS [View1],
  CASE
    WHEN EXISTS (SELECT * FROM View2 WHERE CustomerId = UnionCTE.CustomerID) THEN 'X'
    END AS [View2],
    ...
  CASE
    WHEN EXISTS (SELECT * FROM View7 WHERE CustomerId = UnionCTE.CustomerID) THEN 'X'
    END AS [View7]
FROM UnionCTE
于 2013-03-01T13:09:46.853 に答える
0

CTE、UNION ALL、およびRANK()ランキング関数によるもう 1 つのオプション

 ;WITH cte AS
 (
  SELECT CustomerId, Account, Name, Balance, 'View1' AS [ViewList]
  FROM View1
  UNION ALL
  SELECT CustomerId, Account, Name, Balance, 'View2'
  FROM View2
  UNION ALL
  SELECT CustomerId, Account, Name, Balance, 'View3'
  FROM View3
  UNION ALL
  SELECT CustomerId, Account, Name, Balance, 'View4'
  FROM View4
  UNION ALL
  SELECT CustomerId, Account, Name, Balance, 'View5'
  FROM View5
  UNION ALL
  SELECT CustomerId, Account, Name, Balance, 'View6'
  FROM View6
  UNION ALL
  SELECT CustomerId, Account, Name, Balance, 'View7'
  FROM View7
  ), cte2 AS
 (
  SELECT *, RANK() OVER(PARTITION BY CustomerId ORDER BY [ViewList] ASC) AS rn
  FROM cte  
  )
  SELECT *
  FROM cte2
  WHERE rn = 1

SQLFiddle の簡単な例

于 2013-03-01T14:22:44.287 に答える