2

テーブルのレコードのサブセット、テーブルのすべての列、およびテーブルに特定のタイプのレコードが含まれている場合に値が「X」に設定された追加の「フラグ」列を含むテーブルのビューを作成するにはどうすればよいですか? たとえば、次のリレーション テーブルを考えてみましょう。Relationsここで、型の値は を表しますH'-human, 'D'-dog

 id | type | relation | related
--------------------------------
 H1 |  H   | knows    | D2 
 H1 |  H   | owns     | D2 
 H2 |  H   | knows    | D1 
 H2 |  H   | owns     | D1
 H3 |  H   | knows    | D1
 H3 |  H   | knows    | D2
 H3 |  H   | treats   | D1
 H3 |  H   | treats   | D2
 D1 |  D   | bites    | H3
 D2 |  D   | bites    | H3

このテーブルには、特定の順序のレコードがない場合があります。

Humansからのすべての人と犬のknows関係を含むビューを作成しようとしています のRelationsすべての列と、特定の関係にある人間が誰かを所有している場合のRelations追加の列isOwnerを格納します。'X'

 id | type | relation | related | isOwner
------------------------------------------
 H1 |  H   | knows    |    D2   |    X
 H2 |  H   | knows    |    D1   |    X
 H3 |  H   | knows    |    D1   |    

しかし、これにはかなり苦労しています。CREATE VIEWできれば1回の呼び出しで、または実際に何らかの方法でそれを行う方法を知っていますか?

4

3 に答える 3

3
CREATE VIEW vHumanDogRelations
AS
SELECT
    id,
    type,
    relation,
    related,
    -- Consider using a bit 0/1 instead
    CASE 
        WHEN EXISTS (
            SELECT 1
            FROM Relations
            WHERE 
                id = r.id
                AND related = r.related -- Owns someone or this related only?
                AND relation = 'owns'    
        ) THEN 'X'
        ELSE ''
    END AS isOwner
FROM Relations r
WHERE 
    relation = 'knows'
    AND type = 'H'
    AND related = 'D';
于 2013-11-10T17:57:20.623 に答える
2

select以下をビュー定義に入れることができるはずです

select *, case when exists 
(select * from Relations where id = r.id and relation= 'owns') then 'X'
else '' end as isOwner 
from Relations r
于 2013-11-10T17:58:53.017 に答える
1

PIVOT を使用して目的の結果を達成することもできます。最後のクエリはわかりにくいかもしれないので、メソッドを詳しく説明します。

最初に、値をに置き換えて、Relationansのいずれかまたはからサブセットtypeを導出します。HrelationknowsownsownsX

SELECT
  id,
  type,
  relation = CASE relation WHEN 'owns' THEN 'X' ELSE relation END,
  related
FROM Relations
WHERE type = 'H'
  AND relation IN ('knows', 'owns')

あなたの例に基づいて、これを得るでしょう:

id  type  relation  related
--  ----  --------  -------
H1   H    knows     D2
H1   H    owns      D2
H2   H    knows     D1
H2   H    owns      D1
H3   H    knows     D1
H3   H    knows     D2

次に、この PIVOT 句を最初のクエリの結果に適用します。

PIVOT (
  MAX(relation) FOR relation IN (knows, X)
) AS p

同一の値を持つ行を 1 つの行にグループ化し、 2 つの列にid, type, related分割します。relationknowsX

id  type  related  knows  X
--  ----  -------  -----  ----
H1   H    D2       knows  X
H2   H    D1       knows  X
H3   H    D1       knows  NULL
H3   H    D2       knows  NULL

この時点で、メインの SELECT 句の出力用に列セットをわずかに再配置する必要があるだけで、途中で名前knowsを torelationおよびXtoに変更します。isOwner

SELECT
  id,
  type,
  relation = knows,
  related,
  isOwner = X
...

出力:

id  type  relation  related  isOwner
--  ----  --------  -------  -------
H1   H    knows     D2       X
H2   H    knows     D1       X
H3   H    knows     D1       NULL
H3   H    knows     D2       NULL

もちろん、必要に応じて、NULL を空の文字列に簡単に置き換えることができます。

最後の仕上げとして、この追加のフィルターをメイン クエリに追加します。

WHERE knows IS NOT NULL

実際に犬を知らずに犬を飼っている人がいる可能性がある場合に備えて(そして、それらを出力に含めたくありません)。

したがって、完全なクエリは次のようになります。

SELECT
  id,
  type,
  relation = knows,
  related,
  isOwner = X
FROM (
  SELECT
    id,
    type,
    relation = CASE relation WHEN 'owns' THEN 'X' ELSE relation END,
    related
  FROM Relations
  WHERE type = 'H'
    AND relation IN ('knows', 'owns')
) AS s
PIVOT (
  MAX(relation) FOR relation IN (knows, X)
) AS p
WHERE knows IS NOT NULL
;

このソリューションの SQL Fiddle デモは、こちらから入手できます

于 2013-11-13T00:05:43.323 に答える