Mysql 使用WHERE的(可能)双连接查询中的左连接功能
我有以下三个表格:Mysql 使用WHERE的(可能)双连接查询中的左连接功能,mysql,sql,join,left-join,Mysql,Sql,Join,Left Join,我有以下三个表格: Clients AS c -------- ClientID, ClientGUID, InitializationDate, LastCheckin ClientServices AS cs --------------- ClientID, ServiceID, Status, Version Services AS s --------- ServiceID, Name, Description 我需要构建一个查询,该查询将给出以下结果: s.Name, cs.V
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
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'
Name, Version
InITManager, '0.1'
InITIAM, '0.2'
InITTesting, NULL
客户:
ClientID, ClientGUID, InitializationDate, LastCheckin
1, 'xxxxxxxxxxxxxxxx', 10/10/2017, 10/12/2017
2, 'thisisanewguid', 05/23/2017, 10/12/2017
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'
Name, Version
InITManager, '0.1'
InITIAM, '0.2'
InITTesting, NULL
客户服务:
ClientID, ClientGUID, InitializationDate, LastCheckin
1, 'xxxxxxxxxxxxxxxx', 10/10/2017, 10/12/2017
2, 'thisisanewguid', 05/23/2017, 10/12/2017
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'
Name, Version
InITManager, '0.1'
InITIAM, '0.2'
InITTesting, NULL
服务:
ClientID, ClientGUID, InitializationDate, LastCheckin
1, 'xxxxxxxxxxxxxxxx', 10/10/2017, 10/12/2017
2, 'thisisanewguid', 05/23/2017, 10/12/2017
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'
Name, Version
InITManager, '0.1'
InITIAM, '0.2'
InITTesting, NULL
所需结果集,其中ClientGUID='thisisanewguid':
ClientID, ClientGUID, InitializationDate, LastCheckin
1, 'xxxxxxxxxxxxxxxx', 10/10/2017, 10/12/2017
2, 'thisisanewguid', 05/23/2017, 10/12/2017
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'
Name, Version
InITManager, '0.1'
InITIAM, '0.2'
InITTesting, NULL
您好,请尝试以下查询
SELECT cs.Version, s.Name
FROM ClientServices cs
RIGHT JOIN Clients c ON c.ClientID = cs.ClientID
RIGHT JOIN Services s ON s.ServiceID = cs.ServiceID
对于obatin,您所展示的结果是,您可以使用left table with left join,而不使用where子句来表示所涉及的列id left join
SELECT s.`Name`,
cs.`Version`
FROM `Services` s
LEFT JOIN ClientServices cs ON s.`ServiceID` = cs.`ServiceID`
LEFT JOIN Clients c ON c.ClientID = cs.ClientID AND c.`ClientGUID`='thisisanewguid'
请参见,当找不到结果时,左连接将生成null,如果找不到记录,则内部连接将删除该行。您从表s左连接到cs..开始,所以cs null是有效的,您将看到s的结果,此时没有相应的cs条目。然后从cs内部连接到c…从第一个左连接留下的所有空值现在都在该连接处过滤掉。有道理?左连接后跟内部连接会弄巧成拙。这是有道理的,在它不起作用后我确实想到了这一点,但当我接着尝试两个
左连接时,它仍然不起作用,因为我必须指定其中c.ClientGUID='thisisanewguid'
。事实上,我想得越多,我就越倾向于认为我的第二个查询是唯一的方法。有了它,我就没有办法指定WHERE ClientGUID='thisisanewguid'
谢谢!我从来没有想过或知道你可以在连接中使用“AND”。再次感谢。在这种情况下,您需要和条件,因为如果您使用where,那么您没有左连接,而是内部连接join@ChannaveerHakari .. 谢谢根据你的代码。。建议您使用left join(而不是right)是这种情况下的自然设置方法,它几乎具有我想要的功能。。。但是如果我添加,其中c.ClientGUID='thisisanewguid'
,那么我只得到InITManager和InITIAM。