Sql 与左连接,并且仍在筛选行

Sql 与左连接,并且仍在筛选行,sql,sql-server,join,Sql,Sql Server,Join,我有以下疑问: SELECT c.cardNo, acc.accountId FROM card c LEFT JOIN accounts acc ON c.accId = acc.id 上面的查询返回500行。在上面的查询中,我正在检索所有卡片。我假装看到,作为一个例子,没有账户的卡将返回NULL而不是accountId 然后我想得到所有的卡,只有在欧洲注册的国家的accountId。所以我仍然想要500张卡片,所以我尝试了以下方法: SELECT c.cardNo, acc.account

我有以下疑问:

SELECT c.cardNo, acc.accountId
FROM card c
LEFT JOIN accounts acc ON c.accId = acc.id
上面的查询返回500行。在上面的查询中,我正在检索所有卡片。我假装看到,作为一个例子,没有账户的卡将返回NULL而不是accountId

然后我想得到所有的卡,只有在欧洲注册的国家的accountId。所以我仍然想要500张卡片,所以我尝试了以下方法:

SELECT c.cardNo, acc.accountId
FROM card c
LEFT JOIN accounts acc ON c.accId = acc.id AND acc.registrationContinent = 'EU'
然而,令我惊讶的是,我得到了300行,而不是500行,上面的内容也相当于我有一个WHERE子句


有人能解释一下为什么左联接没有返回卡表中的所有记录吗?

因为您正在筛选不在“EU”中的帐户

如果account.RegistrationContinental不是EU时,您希望accountid中有一个空值,可以这样做

SELECT c.cardNo, 
case when acc.registrationContinent = 'EU' then acc.accountId else NULL end
FROM card c
LEFT JOIN accounts acc ON c.accId = acc.id
但我认为你们有很多信用卡账户,有些是欧盟账户,有些是非欧盟账户

所以在你的第二个查询中,你仍然拥有你所有的牌,我敢打赌,你拥有的不同牌不到500张,可能不到300张

第一个查询将多次返回同一张卡,如果它每次都有多个帐户和不同的帐户

检查一下

select count(*) from card

查看您有多少张不同的卡。

因为您正在筛选不在“EU”中的帐户

如果account.RegistrationContinental不是EU时,您希望accountid中有一个空值,可以这样做

SELECT c.cardNo, 
case when acc.registrationContinent = 'EU' then acc.accountId else NULL end
FROM card c
LEFT JOIN accounts acc ON c.accId = acc.id
但我认为你们有很多信用卡账户,有些是欧盟账户,有些是非欧盟账户

所以在你的第二个查询中,你仍然拥有你所有的牌,我敢打赌,你拥有的不同牌不到500张,可能不到300张

第一个查询将多次返回同一张卡,如果它每次都有多个帐户和不同的帐户

检查一下

select count(*) from card

查看您有多少张不同的卡。

您已经在联接中指定了一个条件,现在这将是表如何匹配在一起的一部分。要获得您想要的结果,您可以使用子查询筛选您加入卡的reulst。像这样:

SELECT c.cardNo,
    acc.accountId
FROM card c
LEFT JOIN (
    SELECT accountId
    FROM accounts
    WHERE registrationContinent = 'EU'
    ) acc
    ON c.accId = acc.id

您已经在联接中指定了一个条件,这将成为表匹配方式的一部分。要获得您想要的结果,您可以使用子查询筛选您加入卡的reulst。像这样:

SELECT c.cardNo,
    acc.accountId
FROM card c
LEFT JOIN (
    SELECT accountId
    FROM accounts
    WHERE registrationContinent = 'EU'
    ) acc
    ON c.accId = acc.id

当您在join语句中有条件时,将过滤第一个数据,然后发生联接。 当您在WHERE中给出条件时,首先发生连接,然后过滤数据

下面的例子可能会对你有所帮助

DECLARE @A TABLE (ID INT, NAME VARCHAR(5), DEPID INT)
DECLARE @B TABLE (DEPID INT, DEPNAME VARCHAR(5),COUNTRY VARCHAR(5))
INSERT INTO @A VALUES (1,'JIT',101),(2,'PAT',101),(3,'JOM',101),(4,'MARK',102),(5,'FAL',103)
INSERT INTO @B VALUES (101,'HR','IND'),(102,'ACC','IND'),(103,'OPER','US')

SELECT      * FROM @A
SELECT      * FROM @B
结果

结果


当您在join语句中有条件时,将过滤第一个数据,然后发生联接。 当您在WHERE中给出条件时,首先发生连接,然后过滤数据

下面的例子可能会对你有所帮助

DECLARE @A TABLE (ID INT, NAME VARCHAR(5), DEPID INT)
DECLARE @B TABLE (DEPID INT, DEPNAME VARCHAR(5),COUNTRY VARCHAR(5))
INSERT INTO @A VALUES (1,'JIT',101),(2,'PAT',101),(3,'JOM',101),(4,'MARK',102),(5,'FAL',103)
INSERT INTO @B VALUES (101,'HR','IND'),(102,'ACC','IND'),(103,'OPER','US')

SELECT      * FROM @A
SELECT      * FROM @B
结果

结果


所有的500张卡都注册为“EU”吗?如果你只做一个SELECT*FROM卡,你会得到多少行?不管名称如何,帐户中是否可能存在具有相同id值的多行?从上面的查询中看不到不同的注册?不,它不像where子句。如果您将acc.registrationContinental='EU'放在where子句中,您将无法获得没有帐户的卡。当你的第二个查询也给出这些结果时,是否所有的500张卡都注册为“EU”如果你只做一个SELECT*FROM卡,你会得到多少行?不管名称如何,帐户中是否可能存在具有相同id值的多行?从上面的查询中看不到不同的注册?不,它不像where子句。如果您将acc.registrationContinental='EU'放在where子句中,您将无法获得没有帐户的卡。而您的第二个查询也会给出这些结果。