我有几张桌子(确切地说,7张)我互相交叉加入。这部分给了我一些问题;
表格“操作”
-----------------------------------------
| ID | Package ID | Action Type | Message |
-----------------------------------------
| 40 | 100340 | 0 | OK |
| 41 | 100340 | 12 | Error |
| 42 | 100340 | 2 | OK |
| 43 | 100341 | 4 | OK |
| 44 | 100341 | 0 | Error |
| 45 | 100341 | 12 | OK |
-----------------------------------------
表格“套餐”
----------------------
| ID | Name |
----------------------
| 100340 | Testpackage |
| 100341 | Package xy |
----------------------
我完成了交叉连接,但是当Package
中没有指定ID的Actions
时,该包上的所有操作都完全丢失,而不仅仅是Name
空白 - 这就是我想要的。
因此,如果缺少引用,只需将相应的连接列留空或作为空字符串......:
----------------------------------------------------------------------
| Package ID | Name | Action 0 | Action 2 | Action 4 | Action 12 |
----------------------------------------------------------------------
| 100340 | Testpackage | OK | OK | | Error |
| 100341 | Package xy | Error | | OK | OK |
----------------------------------------------------------------------
这怎么可能?
修改
抱歉,我刚看到我的示例完全错误,我更新了它最终应该是什么样子。
我当前的查询看起来像这样(如上所述,只是一个提取,因为实际的查询大约是三倍,包括更多的表)
SELECT
PackageTable.ID AS PackageID,
PackageTable.Name,
Action0Table.Message AS Action0,
Action2Table.Message AS Action2,
Action4Table.Message AS Action4,
Action12Table.Message AS Action12
FROM
Packages AS PackageTable LEFT OUTER JOIN
Actions AS Action0Table ON PackageTable.ID = Action0Table.PackageID LEFT OUTER JOIN
Actions AS Action2Table ON PackageTable.ID = Action2Table.PackageID LEFT OUTER JOIN
Actions AS Action4Table ON PackageTable.ID = Action4Table.PackageID LEFT OUTER JOIN
Actions AS Action12Table ON PackageTable.ID = Action12Table.PackageID
WHERE
Action0Table.ActionType = 0 AND
Action2Table.ActionType = 2 AND
Action4Table.ActionType = 4 AND
Action12Table.ActionType = 12
答案 0 :(得分:5)
那么为什么你不能只做一个外部的JOIN,例如:
SELECT `Package ID`, Name, `Action Type`, `Action Date`
FROM Actions
LEFT OUTER JOIN Packages
ON Actions.`Package ID` = Packages.`Package ID`
答案 1 :(得分:4)
你有'where'条款,不包括遗失的行动记录吗?即使您使用外部联接,仍然会应用您的where子句,如果它们不匹配,则不会包含操作记录。
编辑:问题是你的ActionType过滤器。如果没有匹配的操作记录,则ActionType为null,与您的任何过滤器都不匹配。因此,您可以在where子句中添加“或ActionType为null”。我不知道您的业务需求,但这可能包含超出您想要的记录。
答案 2 :(得分:2)
正如其他人所说,我也有同样的答案。
只是显示不同的结果
declare @Actions table(id int , packageid int, actiontype int,dt date)
declare @Packages table(id int,name varchar(50))
insert into @Actions
select 40,100340,0,'2009/01/01 3:00pm' union all
select 41,100340,12,'2009/01/01 5:00pm' union all
select 42,100340,2,'2009/01/01 5:30pm' union all
select 43,100341, 4,'2009/01/02 8:00am'
insert into @Packages
select 100340,'Testpackage'
左外连接查询
select a.packageid,p.name,a.actiontype,a.dt
from @Actions a
left join @Packages p
on a.packageid = p.id
完全加入(在这种情况下,您将获得相同的结果)
select a.packageid,p.name,a.actiontype,a.dt
from @Actions a
full join @Packages p
on a.packageid = p.id
输出:
packageid name actiontype dt
100340 Testpackage 0 2009-01-01
100340 Testpackage 12 2009-01-01
100340 Testpackage 2 2009-01-01
100341 NULL 4 2009-01-02
内部联接查询(您不想要)
select a.packageid,p.name,a.actiontype,a.dt
from @Actions a
join @Packages p
on a.packageid = p.id
<强>输出:强>
packageid name actiontype dt
100340 Testpackage 0 2009-01-01
100340 Testpackage 12 2009-01-01
100340 Testpackage 2 2009-01-01
答案 3 :(得分:2)
您将离开(外部)加入包裹表。这意味着如果记录不在packages表中(连接条件左侧的表),则不要将其包含在最终结果中。
您可以在动作表上进行正确(外部)联接,在这种情况下,您将获得所有动作记录,无论它们是否在包表中匹配。
你可以做一个完整的(外部)联接,换句话说,给我两个表中的所有记录。
最后,你可以进行内连接,或两个表中都有的记录。
您可能会发现在此处绘制维恩图是有帮助的,左侧表格为左侧圆圈,右侧表格为右侧圆圈。因此,内连接表示图的重叠区域。
因此,要回答您的问题,您将需要调整您的联接以进行完全外连接或正确连接,具体取决于您是否要查看没有操作的包。并且你将需要调整你的where子句以包括许多其他海报所建议的空行动。虽然您可能希望向其中添加一个附加子句,其中表达式排除所有操作都为空的记录。另外,在编写示例时,您只会看到包中的操作为0,2,4和12的包;根据您提供的信息,这听起来不正确。
SELECT
PackageTable.ID AS PackageID,
PackageTable.Name,
Action0Table.Message AS Action0,
Action2Table.Message AS Action2,
Action4Table.Message AS Action4,
Action12Table.Message AS Action12
FROM
Packages AS PackageTable
RIGHT OUTER JOIN Actions AS Action0Table ON
PackageTable.ID = Action0Table.PackageID
RIGHT OUTER JOIN Actions AS Action2Table ON
PackageTable.ID = Action2Table.PackageID
RIGHT OUTER JOIN Actions AS Action4Table ON
PackageTable.ID = Action4Table.PackageID
RIGHT OUTER JOIN Actions AS Action12Table ON
PackageTable.ID = Action12Table.PackageID
WHERE
(Action0Table.ActionType = 0 OR Action0Table.ActionType IS NULL) AND
(Action2Table.ActionType = 2 OR Action2Table.ActionType IS NULL) AND
(Action4Table.ActionType = 4 OR Action4Table.ActionType IS NULL) AND
(Action12Table.ActionType = 12 OR Action12Table.ActionType IS NULL) AND
NOT (Action0Table.ActionType IS NULL AND Action2Table.ActionType IS NULL AND
Action4Table.ActionType IS NULL AND Action12Table.ActionType IS NULL)
如果要查看没有任何这些操作的包,则需要删除该最终的NOT子句。此外,根据数据的质量,一旦开始包含空值,您可能会开始接收重复记录;在这种情况下,你的问题变得更难解决,你需要回到我们身边。
答案 4 :(得分:1)
阅读'外部联接'
答案 5 :(得分:1)
而不是INNER JOIN使用LEFT JOIN。这将成为.-