Как найти только самую раннюю дату - PullRequest
0 голосов
/ 16 мая 2019

Мне нужно, чтобы мой вывод выглядел следующим образом

job_id      po_id       po_date     vendor_id
----------  ----------  ----------  ----------
005         FFF         1989-12-01  ABC
004         CCC         1990-01-05  SOS
006         GGG         1988-07-15  XYZ

Когда я сейчас получаю это

job_id      po_id       po_date     vendor_id
----------  ----------  ----------  ----------
002         AAA         1990-05-20  ABC
004         DDD         1990-01-01  ABC
005         FFF         1989-12-01  ABC
004         CCC         1990-01-05  SOS
005         EEE         1990-01-15  SOS
002         BBB         1990-03-15  XYZ
006         GGG         1988-07-15  XYZ

Мне бы хотелось, чтобы в моем коде отображались только самые ранние даты каждого vendor_id

любая помощь приветствуется, и я должен сделать это на SQL lite, и я не могу использовать group by, это мой текущий код

select job_id, po_id, po_date, vendor_id
from pos
where po_date >=
  (Select min(po_date)
  from pos )
  order by vendor_id;

Ответы [ 2 ]

0 голосов
/ 16 мая 2019

Если вы используете Sqlite 3.25 или новее, это легко сделать с помощью оконных функций:

SELECT job_id, po_id, po_date, vendor_id
FROM (SELECT *, rank() OVER (PARTITION BY vendor_id ORDER BY po_date) AS rn FROM pos)
WHERE rn = 1
ORDER BY vendor_id;

По сути, это разбивает все строки таблицы на vendor_id (очень похоже на концепцию GROUP BY, за исключением того, что применяется ко всем строкам результата, а не при генерации строк результата) и сортирует каждый раздел по po_date , а затем нумерует их в соответствии с их ранжированием - все заказы на поставку на самую раннюю дату для каждого поставщика будут иметь ранг 1. Тогда внешний запрос выбирает только эти строки ранга 1.

Для достижения наилучших результатов используйте индекс pos(vendor_id, po_date).


Подход не оконной функции, который не использует GROUP BY или JOIN в соответствии с требованиями OP. Этот действительно нуждается в вышеупомянутом индексе, чтобы минимизировать полное сканирование таблицы.

SELECT job_id, po_id, po_date, vendor_id
FROM pos AS p1
WHERE po_date = (SELECT min(p2.po_date) FROM pos AS p2 WHERE p1.vendor_id = p2.vendor_id)
ORDER BY vendor_id;

Сравните это с вопросом в вашем вопросе; вы просто упустили возможность ограничить подзапрос текущей строкой vendor_id и сравнением правильной даты.

0 голосов
/ 16 мая 2019

С помощью этого запроса:

select vendor_id, min(po_date) po_date
from pos
group by vendor_id

вы получаете самые ранние po_date для каждого vendor_id, а затем вы должны присоединить его к таблице:

select p.job_id, p.po_id, p.po_date, p.vendor_id
from pos p inner join (
  select vendor_id, min(po_date) po_date
  from pos
  group by vendor_id
) g on g.vendor_id = p.vendor_id and g.po_date = p.po_date
order by p.vendor_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...