У меня есть таблица «заемщик», которая соединена с таблицей «ссуды». Я пытаюсь вернуть всех заемщиков, у которых НЕТ ссуды в определенный день. Это код, который у меня есть до сих пор, и я наткнулся на небольшую стену, поскольку, похоже, это способ сделать это, по общему признанию, я новичок в SQL, и я могу быть далеко, но любая помощь будет принята с благодарностью. Я возвращаю всех заемщиков, используя этот код, а не 60 или около того, как мне следовало бы. Спасибо!

SELECT DISTINCT b.cardno, b.fname ||' '|| b.lname AS "BORROWER NAME"
FROM borrower b
JOIN loan l ON b.cardno = l.cardno
WHERE '01/SEP/05' NOT BETWEEN l.dateout AND l.datein
ORDER BY b.cardno;

Используя ссылку, предоставленную на некоторую информацию, мне удалось немного уменьшить установленную доходность, но по-прежнему возвращаю слишком много заемщиков:

SELECT DISTINCT b.cardno, b.fname ||' '|| b.lname AS "BORROWER NAME"
FROM borrower b
JOIN loan l ON b.cardno = l.cardno
where l.dateout < '01/SEP/05'
and l.datein > '01/SEP/05'
ORDER BY b.cardno;
0
Hard_Whey 20 Май 2021 в 12:42

1 ответ

Лучший ответ

Ваш запрос будет искать все ссуды в любой другой день; поэтому из него будут исключены только те, у кого только была книга в этот день. Если вы изменили первую строку на:

SELECT b.cardno, b.fname ||' '|| b.lname AS "BORROWER NAME", l.dateout, l.datein

Вы бы не увидели все ссуды в тот день; так что все (или почти все) заемщики, но не все ссуды.

Но «01 / SEP / 05» - это не свидание; вы полагаетесь на неявное преобразование с использованием настроек сеанса, что не является хорошей идеей, и вы можете получить значения, которых вы не ожидаете, что может означать, что сопоставление дат в любом случае работает не так, как вы ожидаете. Лучше использовать to_date() с подходящей маской формата, желательно с 4-значными годами; или литерал даты, например DATE '2005-09-01'.

Вы можете использовать not exists с чем-то вроде:

SELECT b.cardno, b.fname ||' '|| b.lname AS "BORROWER NAME"
FROM borrower b
WHERE NOT EXISTS (
  SELECT null
  FROM loan l
  WHERE l.cardno = b.cardno
  AND DATE '2005-09-01' BETWEEN l.dateout AND l.datein
)
ORDER BY b.cardno;

Даже там совпадение даты может не совсем работать, если ваша дата входа / выхода имеет фактическое время, а не полночь. Любые ссуды, предоставленные после полуночи целевой даты, будут исключены. Вместо этого вы можете сделать это:

  AND l.dateout < DATE '2005-09-01' + 1
  AND l_datein >= DATE '2005-09-01'
4
Alex Poole 20 Май 2021 в 10:19