至少对我来说很有趣......
说我有两张桌子:
myLookUpTable:
lookupId | Name
-------- -----
1 Red
2 Green
3 Blue
和InfoTable:
infoId lookupId Amount ParentId
------ -------- ------ --------
1 1 2 332
2 3 14 332
我如何编写一个返回myLookUpTable
中每一行的查询,并包含来自InfoTable的相关信息(如果某个ParentId存在?)
示例:
查询parentId 221将返回Name
和Amount
的以下内容:
Name Amount
---- ------
Red
Green
Blue
并查询parentId 332将返回Name
和Amount
的以下内容:
Name Amount
---- ------
Red 2
Green
Blue 14
我尝试了左边连接的十种变化而没有运气。以下是我的最新消息:
SELECT mlut.Name, it.Amount
FROM myLookUpTable as mlut
LEFT JOIN InfoTable as it
ON mlut.lookupId = it.lookUpId OR it.ParentId is null
where it.ParentId = 332
这似乎是一个简单的问题,我只是在寻找一些东西吗?
答案 0 :(得分:7)
我认为这会做你想要的。
SELECT mlut.Name, it.Amount
FROM myLookUpTable as mlut
LEFT JOIN InfoTable as it
ON mlut.lookupId = it.lookUpId
AND it.ParentId = 332
SQL Server 2005测试结果
CREATE TABLE [dbo].[myLookUpTable](
[lookupId] [int] NOT NULL,
[Name] [varchar](10) NOT NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[InfoTable](
[infoId] [int] NOT NULL,
[lookupId] [int] NOT NULL,
[Amount] [int] NOT NULL,
[ParentId] [int] NOT NULL
) ON [PRIMARY]
INSERT INTO myLookUpTable Values (1,'Red')
INSERT INTO myLookUpTable Values (2,'Green')
INSERT INTO myLookUpTable Values (3,'Blue')
INSERT INTO infoTable Values (1,1,2,332)
INSERT INTO infoTable Values (2,3,14,332)
SELECT mlut.Name, it.Amount
FROM myLookUpTable as mlut
LEFT JOIN InfoTable as it
ON mlut.lookupId = it.lookUpId
AND it.ParentId = 221
Red NULL
Green NULL
Blue NULL
SELECT mlut.Name, it.Amount
FROM myLookUpTable as mlut
LEFT JOIN InfoTable as it
ON mlut.lookupId = it.lookUpId
AND it.ParentId = 332
Red 2
Green NULL
Blue 14
答案 1 :(得分:1)
OR it.ParentId is null
部分不应该存在。
否则 - 看起来不错。如果您遇到一些特殊问题,请说明一下。
答案 2 :(得分:0)
问题在于这一行:
where it.ParentId = 332
当你在where where条件下使用它时,你将消除任何没有ParentId的行,例如左边没有连接行的表中的行。使用:
where it.ParentId IS NULL or it.ParentId = 332
从连接语句中删除IS NULL检查。
答案 3 :(得分:0)
而不是
where it.ParentId = 332
你需要做
AND it.ParentId = 332
还要摆脱OR it.ParentId is null
答案 4 :(得分:0)
ParentID的WHERE子句用于撤消LEFT JOIN所有空查找值的工作。 您可以将该约束移动到LEFT JOIN条件:
SELECT mlut.Name, it.Amount
FROM myLookUpTable as mlut
LEFT JOIN InfoTable as it
ON mlut.lookupId = it.lookUpId AND it.ParentId = 332
答案 5 :(得分:0)
Dave Barker的帖子是正确答案但是: 如果您总是需要返回与myLookUpTable中的行数匹配的确切行数,并且(lookupid,ParentId)在InfoTable中不是唯一的,您可能需要使用以下选项之一:
-- sample contents - note that there are multiple amounts for lookupid, parentid (3,332)
INSERT INTO infoTable Values (1,1,2,332)
INSERT INTO infoTable Values (2,3,14,332)
INSERT INTO infoTable Values (3,3,24,332)
INSERT INTO infoTable Values (4,3,34,0)
INSERT INTO infoTable Values (5,3,44,332)
-- option 1
SELECT mlut.Name, it.Amount
FROM myLookUpTable as mlut
LEFT JOIN
(
SELECT lookUpId, SUM(Amount) as Amount
FROM InfoTable
WHERE ParentId = 332
GROUP BY lookupId
) as it
ON mlut.lookupId = it.lookUpId
-- option 2
SELECT mlut.Name, it.Amount
FROM myLookUpTable as mlut
LEFT JOIN
(
SELECT lookUpId, ParentId, SUM(Amount) as Amount
FROM InfoTable
GROUP BY lookupId, ParentId
) as it
ON mlut.lookupId = it.lookUpId
AND it.ParentId = 332
-- option 2 using CTE
;WITH it AS (
SELECT lookUpId, ParentId, SUM(Amount) as Amount
FROM InfoTable
GROUP BY lookupId, ParentId
)
SELECT mlut.Name, it.Amount
FROM myLookUpTable as mlut
LEFT JOIN it
ON mlut.lookupId = it.lookUpId
AND it.ParentId = 332
/*
Name Amount
---------- -----------
Red 2
Green NULL
Blue 82
*/