Можете ли вы иметь несколько выборочных состояний на одной таблице, а затем присоединиться к ним?
Обратите внимание, что я не разработчик, поэтому любая помощь здесь будет принята с благодарностью.
Моя проблема: у меня есть список в Oracle Responsys, который содержит всех клиентов, забронированных в туре. Я хочу найти все записи, в которых отсутствуют значения для FIRST_NAME (это может быть Tba/Tbc/Null), поэтому я могу отправить главному заказчику электронное письмо с просьбой обновить данные об имени для своих дополнительных гостей.
Главный букер всегда будет иметь значение CUSTOMER_ID_, оканчивающееся на "-1". Записи с пропущенными значениями имени не будут.
То, что я хочу сделать, это выбрать все записи из списка, в которых отсутствуют первые имена, сгруппировать их по BOOKING_LOCATOR (значение, которое используется главным бухгалтером и его дополнительными гостями) - ТОЛЬКО вернуть только основные книги (записи с CUSTOMER_ID_ заканчивающийся на '-1'.
Пока что я собрал воедино эту грубую идею о том, что я ищу после просмотра других постов, но это не дает ничего похожего на то, что я ищу:
SELECT $A$.BOOKING_LOCATOR, $A$.CUSTOMER_ID_, $A$.EMAIL_ADDRESS_
FROM
(
SELECT $A$.BOOKING_LOCATOR FROM $A$ WHERE ($A$.FIRST_NAME IN ('TBA', 'TBC', 'Tba', 'Tbc') OR $A$.FIRST_NAME IS NULL) AND $A$.POLAR_BOOKING_STATUS != 'C' AND $A$.BOOKING_STATUS != 'Waitlist' AND $A$.EMBARK_DATE >= SYSDATE+1
GROUP BY $A$.BOOKING_LOCATOR
) $A$
INNER JOIN (
SELECT $A$.BOOKING_LOCATOR AS BOOKINGNUM, $A$.CUSTOMER_ID_, $A$.EMAIL_ADDRESS_ FROM $A$ WHERE $A$.CUSTOMER_ID_ LIKE '%-1'
) $A$ ON $A$.BOOKING_LOCATOR = $A$.BOOKINGNUM
Кто-нибудь может направить меня в правильном направлении?
3 ответа
Дайте имя для подвыборов:
SELECT A.BOOKING_LOCATOR, B.CUSTOMER_ID_, B.EMAIL_ADDRESS_
FROM
(
SELECT $A$.BOOKING_LOCATOR FROM $A$ WHERE ($A$.FIRST_NAME IN ('TBA', 'TBC', 'Tba', 'Tbc') OR $A$.FIRST_NAME IS NULL) AND $A$.POLAR_BOOKING_STATUS != 'C' AND $A$.BOOKING_STATUS != 'Waitlist' AND $A$.EMBARK_DATE >= SYSDATE+1
GROUP BY $A$.BOOKING_LOCATOR
) A
INNER JOIN (
SELECT $A$.BOOKING_LOCATOR AS BOOKINGNUM, $A$.CUSTOMER_ID_, $A$.EMAIL_ADDRESS_ FROM $A$ WHERE $A$.CUSTOMER_ID_ LIKE '%-1'
) B ON A.BOOKING_LOCATOR = B.BOOKINGNUM;
Да, вы можете сделать это. Вы можете использовать Joins ИЛИ OUTER APPLY для этого.
SELECT A.BOOKING_LOCATOR, B.CUSTOMER_ID_, B.EMAIL_ADDRESS_
FROM
(
SELECT $A$.BOOKING_LOCATOR FROM $A$ WHERE ($A$.FIRST_NAME IN ('TBA', 'TBC', 'Tba',
'Tbc') OR $A$.FIRST_NAME IS NULL) AND $A$.POLAR_BOOKING_STATUS != 'C' AND
$A$.BOOKING_STATUS != 'Waitlist' AND $A$.EMBARK_DATE >= SYSDATE+1
GROUP BY $A$.BOOKING_LOCATOR
) A
INNER JOIN (
SELECT $A$.BOOKING_LOCATOR AS BOOKINGNUM, $A$.CUSTOMER_ID_, $A$.EMAIL_ADDRESS_ FROM
$A$ WHERE $A$.CUSTOMER_ID_ LIKE '%-1'
) B ON A.BOOKING_LOCATOR = B.BOOKINGNUM;
Опция -2ND - с помощью OuterAPPLY.
SELECT A.BOOKING_LOCATOR, B.CUSTOMER_ID_, B.EMAIL_ADDRESS_
FROM
(
SELECT $A$.BOOKING_LOCATOR FROM $A$ WHERE ($A$.FIRST_NAME IN ('TBA', 'TBC', 'Tba',
'Tbc') OR $A$.FIRST_NAME IS NULL) AND $A$.POLAR_BOOKING_STATUS != 'C' AND
$A$.BOOKING_STATUS != 'Waitlist' AND $A$.EMBARK_DATE >= SYSDATE+1
GROUP BY $A$.BOOKING_LOCATOR
) A
Outer APPLY(
SELECT $A$.BOOKING_LOCATOR AS BOOKINGNUM, $A$.CUSTOMER_ID_, $A$.EMAIL_ADDRESS_ FROM
$A$ WHERE $A$.CUSTOMER_ID_ LIKE '%-1'
) B ON A.BOOKING_LOCATOR = B.BOOKINGNUM;
Если вы хотите, чтобы бронирование находилось и основной клиент, то EXISTS
приходит на ум:
SELECT . . . -- whatever columns you want
FROM $A$ a1
WHERE a.CUSTOMER_ID_ LIKE '%-1' AND
EXISTS (SELECT 1
FROM $A$ a
WHERE a.FIRST_NAME IN ('TBA', 'TBC', 'Tba', 'Tbc') OR a.FIRST_NAME IS NULL) AND
a.POLAR_BOOKING_STATUS <> 'C' AND
a.BOOKING_STATUS <> 'Waitlist' AND
a.EMBARK_DATE >= SYSDATE+1 AND
a.BOOKING_LOCATOR = a1.BOOKING_LOCATOR
);
Это возвращает только одну строку для каждого основного клиента.