sql 中的替代项

Alternate of except in sql

我想使用 except 的替代方法。我使用了左连接,但它没有带来所需的列数据。

SELECT ACCOUNT_NO, BILL_CYCLE_DATE, 2 FROM CSS_BILL_Job 
WHERE (BILL_CYCLE_DATE = 20190526 OR  BILL_CYCLE_DATE = 20190525) --33612
EXCEPT
SELECT DISTINCT ACCOUNT_NO, BILL_CYCLE_DATE, 2  FROM TempNotRunResults --33505

但是现在当我使用 LEFT JOIN 时。

SELECT A.ACCOUNT_NO, A.BILL_CYCLE_DATE, B.DATE_BILLED,
B.DATE_PAYMENT_DUE,B.TOTAL_BILL_AMT, B.LPC_AMT, B.BILL_FREQ, B.BILL_CYCLE_TYPE
FROM CSS_BILL_Job A LEFT JOIN TempNotRunResults B
ON A.ACCOUNT_NO  = B.ACCOUNT_NO
WHERE (A.BILL_CYCLE_DATE = 20190526 OR  A.BILL_CYCLE_DATE = 20190525)
AND A.ACCOUNT_NO NOT IN ( SELECT ACCOUNT_NO FROM TempNotRunResults)

我看到 B.DATE_PAYMENT_DUE、B.TOTAL_BILL_AMT、B.LPC_AMT、B.BILL_FREQ、B.BILL_CYCLE_TYPE 为空,这是不对的。如何在左连接查询中填充来自 table B 的列?

如果您不想要 table TempNotRunResults 中的空值,则使用此连接:

SELECT A.ACCOUNT_NO, A.BILL_CYCLE_DATE, B.DATE_BILLED,
B.DATE_PAYMENT_DUE,B.TOTAL_BILL_AMT, B.LPC_AMT, B.BILL_FREQ, B.BILL_CYCLE_TYPE
FROM CSS_BILL_Job A LEFT JOIN TempNotRunResults B
ON A.ACCOUNT_NO = B.ACCOUNT_NO 
WHERE 
  (A.BILL_CYCLE_DATE = 20190526 OR  A.BILL_CYCLE_DATE = 20190525)
  AND 
  B.ACCOUNT_NO IS NOT NULL

条件 B.ACCOUNT_NO IS NOT NULL 只获取匹配的行,这也可以通过使用 INNER 连接来完成:

SELECT A.ACCOUNT_NO, A.BILL_CYCLE_DATE, B.DATE_BILLED,
B.DATE_PAYMENT_DUE,B.TOTAL_BILL_AMT, B.LPC_AMT, B.BILL_FREQ, B.BILL_CYCLE_TYPE
FROM CSS_BILL_Job A INNER JOIN TempNotRunResults B
ON A.ACCOUNT_NO = B.ACCOUNT_NO
WHERE (A.BILL_CYCLE_DATE = 20190526 OR  A.BILL_CYCLE_DATE = 20190525)


但是你的问题标题是:"Alternate of except in sql",和你说的要达到的目的相反:在我的左连接查询中从 table B 填充列,因为如果你想从 table B 填充行,那么你需要匹配的行。

看来你不太明白EXCEPT的作用。它 returns 第一个结果集中的不同行与第二个结果集中的任何内容都不匹配。请注意,使用 distinct 生成第二个结果集没有任何用处。

要使用联接获得相同的结果,您需要进行外部联接(就像您所做的那样),但要测试未保留的 table (TempNotRunResults) 中的 non-existence 行。所以像:

set nocount on;

declare @bill table (account_no tinyint, bill_cycle  date);
insert @bill (account_no, bill_cycle) values 
(1, '20190531'), 
(1, '20190430'), 
(2, '20190215'), 
(1, '20190531'); -- notice the duplicate for <1, May 31>

declare @notrun table (account_no tinyint, bill_cycle date);
insert @notrun (account_no, bill_cycle) values 
(1, '20190430'), 
(1, '20190630'), 
(1, '20190430'); -- notice the duplicate for <1, Apr 30>

select account_no, bill_cycle from @bill 
except 
select account_no, bill_cycle from @notrun
;

select bl.account_no, bl.bill_cycle 
from @bill as bl left join @notrun as nr 
on bl.account_no = nr.account_no 
and bl.bill_cycle = nr.bill_cycle
where nr.account_no is null
order by bl.account_no, bl.bill_cycle ;

注意加入版本中的重复项。 EXCEPT 删除重复项。由于 EXCEPT 告诉我们在 TempNotRunResults 中没有匹配项,因此在加入时尝试包含来自 table 的列是没有意义的 - 很简单,有 none 并且除了 NULL 之外你不应该期望任何东西。但是,您确实在加入版本中单独加入了 ACCOUNT_NO。这是非常不同的逻辑,所以很难知道你到底想要完成什么。这让我们回到 Han 的请求 - post 示例数据和您的预期结果。