如何在没有联盟的情况下为其孩子选择一排和其他行?
-
18-09-2019 - |
题
我有一个父母和子表,想创建一个选择语句,给定父母ID,返回该父母的一行,并且 其他行 每个孩子。当一个或多个孩子存在时,做左联接并不是给我为父母的行。我知道这可以通过工会来完成,但我正在寻找一种解决方案 才不是 使用工会声明。这可能吗?
父表
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
解决方案
有一个肮脏的黑客:
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*
这应该为您提供想要的结果...希望。
其他提示
您需要执行此一次时间表设置(如果您不想使用数字表,请参见下面的替代解决方案):
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)
设置数字表后,请使用此查询:
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)
替代解决方案 如果您不想创建数字表,则可以使用此方法,返回与上述相同的输出:
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
我试图使用CTE扩展父行,但是如果不使用联盟,这很难!
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
不隶属于 StackOverflow