我有以下3个表:LEFT JOIN的(也许)功能,双连接查询的WHERE
Clients AS c
--------
ClientID,
ClientGUID,
InitializationDate,
LastCheckin
ClientServices AS cs
---------------
ClientID,
ServiceID,
Status,
Version
Services AS s
---------
ServiceID,
Name,
Description
我需要建立一个查询,这将使我的结果如下:
s.Name, cs.Version
我需要它充当左连接,因为我希望显示所有服务,而不管该服务是否在ClientServices中。在这种情况下,所选版本将简单显示为NULL
。
我尝试做一些简单的连接,但是我使用的每个组合LEFT JOIN
和JOIN
都只会导致属于该客户端的ClientServices
出现。举个例子:
SELECT s.`Name`,
cs.`Version`
FROM `Services` s LEFT JOIN ClientServices cs ON
s.`ServiceID` = cs.`ServiceID`
JOIN Clients c ON
cs.`ClientID` = c.`ClientID`
WHERE `ClientGUID`='thisisanewguid'
我能够最终与此查询得到期望的结果:
SELECT s.`Name`,
cs.`Version`
FROM `Services` s LEFT JOIN ClientServices cs
ON s.`ServiceID` = cs.`ServiceID`
WHERE cs.ClientID = (
SELECT ClientID
FROM Clients
WHERE ClientGUID='thisisanewguid'
)
OR cs.ClientID IS NULL
,但我觉得好像它有点“哈克”。有没有更好的方法来获得相同的结果集,但没有在一个查询中执行多个选择? (优选仅加入,但我不知道如果多数民众赞成可能的了)
示例数据集中:
客户:
ClientID, ClientGUID, InitializationDate, LastCheckin
1, 'xxxxxxxxxxxxxxxx', 10/10/2017, 10/12/2017
2, 'thisisanewguid', 05/23/2017, 10/12/2017
ClientServices:
ClientID, ServiceID, Status, Version
1, 1, 1, '0.1'
2, 1, 1, '0.1'
2, 2, 1, '0.2'
服务:
ServiceID, Name, Description
1, InITManager, 'Manages and updates all InIT services.'
2, InITIAM, 'InIT's Inventory/Asset Management.'
3, InITTesting, 'testing'
所需的结果集WHERE ClientGUID = 'thisisanewguid':
Name, Version
InITManager, '0.1'
InITIAM, '0.2'
InITTesting, NULL
请参阅https://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very -simple-sql-query – Strawberry
如果未找到任何结果,则左连接会生成null,如果未找到任何记录,则内连接会删除该行。你从表的左边开始连接到cs ..所以cs null是有效的,你会看到s的结果,在这一点上没有对应的cs入口。然后你从cs内部连接到c ...第一个左连接留下的所有空值现在在此连接处被过滤掉。合理?左连接后跟内连接就是自我挫败。 – Twelfth
这是有道理的,我确实没有想到它,但是当我继续尝试两个'LEFT JOIN'时,它仍然不起作用,因为我必须指定'WHERE c.ClientGUID ='thisisanewguid''。事实上,我越想到它,我越倾向于认为我的第二个查询是唯一的方法。 – TheEggSample