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。