首页 > 解决方案 > Postgresql 使用 Limit 和 Order by 没有 select 和 where 大小写

问题描述

所以我想获取最新的 2 行 person_id 并检查 deposit 字段是否减少。

这是我到目前为止所做的;

客户表是;

   person_id  employee_id  deposit  ts 
    101        201         44        2021-09-30 10:12:19+00
    101        201         47        2021-09-30 09:12:19+00
    101        201         65        2021-09-29 09:12:19+00    
    100        200         21        2021-09-29 10:12:19+00
    104        203         54        2021-09-27 10:12:19+00

结果我想要的是;

   person_id  employee_id  deposit  ts                       pre_deposit   pre_ts
    101        201         44        2021-09-30 10:12:19+00    47          2021-09-30 09:12:19+00 

我不想得到deposit:65行,因为我只想检查最后 2 行。47 > 44 所以。我只需要比较最后两行。如果存款在任何其他行减少,我根本不在乎。

    SELECT person_id, 
           employee_id,
           deposit,
           ts,
           lag(deposit) over client_window as pre_deposit,
           lag(ts) over client_window as pre_ts
    FROM customer 
    WINDOW client_window as (partition by person_id order by ts)
    ORDER BY person_id , ts

所以它返回一个包含以下结果的表;

   person_id  employee_id  deposit  ts                       pre_deposit   pre_ts
    101        201         44        2021-09-30 10:12:19+00    47          2021-09-30 09:12:19+00 
    101        201         47        2021-09-30 09:12:19+00    65        null 
    100        200         21        2021-09-29 10:12:19+00    null        2021-09-29 09:12:19+00
    104        203         54        2021-09-27 10:12:19+00    null        null

但如果我执行以下操作;

SELECT person_id, 
       employee_id,
       deposit,
       ts,
       lag(deposit) over client_window as pre_deposit,
       lag(ts) over client_window as pre_ts
FROM customer 
WINDOW client_window as (partition by person_id order by ts limit 2)

此查询不起作用,因为它会引发错误;

ERROR:  syntax error at or near "limit"
LINE 11:    limit 2

那么如何限制比较最后两行呢?其中 pre_deposit > 存款

标签: sqlpostgresql

解决方案


你很接近。在您稍作修改的第一个查询中使用这个出色distinct on的功能,您就在那里。

select distinct on (person_id) *
from 
(
 select person_id, employee_id, deposit, ts, 
        lead(deposit) over w as pre_deposit, 
        lead(ts) over w as pre_ts 
 from customer
 window w as (partition by person_id order by ts desc)
) t 
where pre_deposit > deposit
order by person_id, ts desc;

SQL Fiddle在这里


推荐阅读