Альтернатива кроме в sql - PullRequest
0 голосов
/ 02 июля 2019

Я хочу использовать альтернативу, кроме. Я использовал левое соединение, но оно не приносит необходимые данные столбца.

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)

Я вижу NULLS для B.DATE_PAYMENT_DUE, B.TOTAL_BILL_AMT, B.LPC_AMT, B.BILL_FREQ, B.BILL_CYCLE_TYPE, что неверно. Как заполнить столбцы из таблицы B в моем запросе левого соединения?

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

Кажется, вы не совсем понимаете, что делает, КРОМЕ. Он возвращает отдельные строки из первого набора результатов, которые не соответствуют чему-либо во втором наборе результатов. И обратите внимание, что использование различных для генерации второго набора результатов не имеет никакого полезного эффекта.

Чтобы получить эквивалентный результат с помощью объединения, вам необходимо выполнить внешнее объединение (как вы это сделали), но проверить на отсутствие строк в незарезервированной таблице (TempNotRunResults). Так что-то вроде:

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 говорит нам, что в TempNotRunResults нет совпадений, нет смысла пытаться включать столбцы из этой таблицы при присоединении - просто их нет, и вам не следует ожидать ничего, кроме NULL. Однако вы присоединились только к ACCOUNT_NO в своей версии для присоединения. Это совсем другая логика, поэтому трудно понять, чего именно вы пытаетесь достичь. И это возвращает нас к запросу от Хана - опубликуйте образцы данных и ожидаемые результаты.

0 голосов
/ 02 июля 2019

Если вам не нужны значения null из таблицы 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)


Но заголовок вашего вопроса звучит так: "Альтернатива кроме в sql" , что противоположно тому, что вы говорите, чего хотите достичь: заполнение столбцов из таблицы B в моем левом запросе соединения , потому что, если вы хотите заполнить строки из таблицы B, вам нужны соответствующие строки.

...