Как запрашивать данные с помощью агрегатов плюс где?

Привет, мне нужна помощь для начинающих. Найдите номер карты и дату заемщика, самый ранний кредит для всех заемщиков, у которых был кредит до 3 января 2004 года, или кто заимствовал книгу, опубликованную до 1920 года? Мой код:

select l.cardno, MIN(l.dateout)
 from loan l
 where l.isbn in (select b.isbn from book b
 where b.yearpublished < '1920')
 having MIN(l.dateout) <= '03-JAN-04'
 group by l.cardno
 order by l.cardno asc;
2 ответа

Это интересный вопрос, и это немного сложно. У вашего подхода есть два условия, но оба условия должны быть выполнены, и вопрос требует or. Это дает вам два варианта: найти способ получить оба условия в одно и то же предложение (where или having) или использовать запрос объединения.

Чтобы получить оба условия в одном и том же пункте, подумайте о втором условии: "Позвольте мне подсчитать количество книг, опубликованных до 1920 года, и сохранить кого-либо, где это число больше 1". Это условие можно перейти к having п.

Остальная часть логики просто заменяет in на join. Следующий запрос предполагает, что все кредиты имеют действительный isbn в таблице книг (в противном случае используйте left join):

select l.cardno, MIN(l.dateout)
from loan l left join
 book b
 on l.isbn = b.isbn
having MIN(l.dateout) <= date '2004-01-01' or
 sum(case when b.yearpublished < 1920 then 1 else 0 end) > 0
group by l.cardno
order by l.cardno asc;

Обратите внимание, что я заменил форматированную дату date Oracle конструкцией date. Это позволяет использовать стандартные форматы даты ISO.


Я получил решение! Благодаря тому, кто дал мне эту идею, я просто что-то изменил, и это ушило!

select l.cardno, MIN(l.dateout)
from loan l left join
 book b
 on l.isbn = b.isbn
having MIN(l.dateout) < date '2004-01-03' or
 sum(case when b.yearpublished <= 1920 then 1 else 0 end) > 0
group by l.cardno
order by l.cardno asc;

licensed under cc by-sa 3.0 with attribution.