如何仅查找最早的日期

时间:2019-05-16 15:31:36

标签: sql sqlite

我需要我的输出看起来像这样

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 :(得分:0)

使用此查询:

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

答案 1 :(得分:0)

如果您使用的是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非常相似,只是它应用于所有结果行,而不是在生成结果行时适用),并按{ {1}},然后根据排名对它们进行编号-每个供应商最早的所有采购订单的排名都将为1。然后外部查询只会选择排名为1的那些行。

为获得最佳结果,请在po_date上加一个索引。


根据OP的要求不使用pos(vendor_id, po_date)GROUP BY的非窗口函数方法。 确实需要上述索引,以最大程度地减少对整个表的扫描。

JOIN

将此问题与您的问题进行比较;您几乎只是错过了将子查询限制为当前行的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; 和正确的日期比较。