4

親と子のテーブルがあり、親IDを指定すると、その親の行とすべての子の追加の行を返すselectステートメントを作成したいと思います。左結合を実行しても、1つ以上の子が存在する場合、それ自体で親の行が表示されるわけではありません。これはUNIONで実行できることは知っていますが、unionステートメントを使用しないソリューションを探しています。これは可能ですか?

【親テーブル】

ID     Name
-------------
1    | Bob

【子テーブル】

ID     ParentId   Name
-----------------------
1    | 1        | Jim    
2    | 1        | Ned  

私が探しているクエリ結果:

Parent_Name   Child_Name
---------------------------
Bob         | NULL <- I need this null here
Bob         | Jim
Bob         | Ned
4

3 に答える 3

7

汚い汚いハックを持っている:

SELECT
    P2.Name Parent_Name,
    C.Name  Child_Name
FROM [Parent Table] P1
    FULL OUTER JOIN [Child Table] C
        ON 1=0
    INNER JOIN [Parent Table] P2
        ON IsNull(P1.ID,C.ParentId) = P2.ID
WHERE P2.ID = *ID here*

これにより、必要な結果が得られるはずです...うまくいけば。

于 2009-09-29T22:19:46.310 に答える
2

この1回限りのテーブル設定を行う必要があります(数値テーブルを使用したくない場合は、以下の代替ソリューションを参照してください)。

SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Numbers
    FROM sys.columns s1
    CROSS JOIN sys.columns s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)

Numbersテーブルを設定したら、次のクエリを使用します。

DECLARE @ParentTable table (ID int,Name varchar(20))
DECLARE @ChildTable table (ID int,ParentID int,Name varchar(20))
INSERT INTO @ParentTable VALUES (1,'Bob')
INSERT INTO @ChildTable VALUES (1,1,'Jim')
INSERT INTO @ChildTable VALUES (2,1,'Ned')

SELECT DISTINCT
    dt.Name,c.Name
    FROM (SELECT
                 CASE WHEN n.Number=1 THEN NULL ELSE p.ID END AS ID,p.Name
              FROM @ParentTable           p
                  INNER JOIN Numbers      n ON 1=1
              WHERE p.ID=1 AND n.Number<=2
         ) dt
        LEFT OUTER JOIN @ChildTable c ON dt.ID=c.ParentID
    ORDER BY 1,2

出力:

Name                 Name
-------------------- --------------------
Bob                  NULL
Bob                  Jim
Bob                  Ned

(3 row(s) affected)

Numbersテーブルを作成したくない場合は、このメソッドを使用できる代替ソリューションは、上記と同じ出力を返します。

SELECT DISTINCT
    dt.Name,c.Name
    FROM (SELECT
                 CASE WHEN n.Number=1 THEN NULL ELSE p.ID END AS ID,p.Name
              FROM @ParentTable           p
                  INNER JOIN (SELECT ROW_NUMBER() OVER(ORDER BY object_id) AS Number FROM sys.columns) n ON n.Number<=2
              WHERE p.ID=1 AND n.Number<=2
         ) dt
        LEFT OUTER JOIN @ChildTable c ON dt.ID=c.ParentID
        ORDER BY 1,2

A CTEを使用して親行を拡張しようとしましたが、UNIONを使用しないと困難です。

于 2009-09-29T19:26:34.113 に答える
0

foriamstuの回答は、さらに簡単な回答を探すように私を刺激しました。

DECLARE @ParentTable table (ID int, Name varchar(20))
DECLARE @ChildTable table (ID int,ParentID int, Name varchar(20))
INSERT INTO @ParentTable VALUES (1,'Bob')
INSERT INTO @ChildTable VALUES (1,1,'Jim')
INSERT INTO @ChildTable VALUES (2,1,'Ned')

SELECT DISTINCT
    P1.Name     Parent_Name,
    C.Name      Child_Name
FROM @ParentTable P1
LEFT JOIN @ChildTable C2 ON C2.ParentID = P1.ID
LEFT JOIN @ChildTable C ON C.ParentID = P1.ID AND C.ParentID = C2.ID
WHERE P1.ID = 1
于 2009-09-29T23:46:29.377 に答える