我有以下查询:
SELECT c.cardNo, acc.accountId
FROM card c
LEFT JOIN accounts acc ON c.accId = acc.id
上述查询返回500行。在上面的查询中,我正在检索所有卡片。我假装看到没有帐户的卡(仅作为示例)将返回NULL而不是accountId。
然后我想获得所有卡片,并且只获得在欧洲注册的国家/地区的帐户ID。所以我仍然想要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子句。
有人可以解释为什么LEFT JOIN没有从卡表中返回所有记录吗?
答案 0 :(得分:2)
因为您要过滤不属于“欧盟”的帐户。
如果你想在account.registrationContinent不是EU
时在acc.accountid中使用NULL值,你可以
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
看看你有多少张不同的牌。
答案 1 :(得分:2)
您已在联接中指定了条件,现在这将是表格如何匹配在一起的一部分。要获得您想要的结果,您可以使用子查询来过滤您加入卡片的结果。像这样:
SELECT c.cardNo,
acc.accountId
FROM card c
LEFT JOIN (
SELECT accountId
FROM accounts
WHERE registrationContinent = 'EU'
) acc
ON c.accId = acc.id
答案 2 :(得分:1)
如果在join语句中有条件,则会过滤第1个数据,然后发生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
<强>结果强>
SELECT *
FROM @A A
LEFT JOIN @B B ON A.DEPID = B.DEPID
SELECT *
FROM @A A
LEFT JOIN @B B ON A.DEPID = B.DEPID AND B.COUNTRY = 'US'
<强>结果强>