我有数据:
id | price | date
1 | 25 | 2019-01-01
2 | 35 | 2019-01-01
1 | 27 | 2019-02-01
2 | 37 | 2019-02-01
是否可以编写只返回窗口第一行的查询?类似于LIMIT 1
,但对于窗口OVER( date )
的查询?
我希望下一个结果:
id | price | date
1 | 25 | 2019-01-01
1 | 27 | 2019-02-01
或者如果第一行的行有NULL
,则忽略整个窗口:
id | price | date
1 | NULL | 2019-01-01
2 | 35 | 2019-01-01
1 | 27 | 2019-02-01
2 | 37 | 2019-02-01
结果:
1 | 27 | 2019-02-01
答案 0 :(得分:1)
按date
和id
对行进行排序,并且每个date
仅占第一行。
然后删除价格为NULL的商品。
SELECT *
FROM (SELECT DISTINCT ON (date)
id, price, date
FROM mytable
ORDER BY date, id
) AS q
WHERE price IS NOT NULL;
@Laurenz让我提供更多解释
select distinct on (<fldlist>) * from <table> order by <fldlist+>;
等于更复杂的查询:
select * from (
select row_number() over (partition by <fldlist> order by <fldlist+>) as rn,*
from <table>)
where rn = 1;
这里<fldlist>
应该是<fldlist+>
的开头(或相等)
答案 1 :(得分:0)
正如IRC上的Myon
所说:
如果要在WHERE中使用窗口功能,则需要先将其放入子选择中
因此目标查询是:
select * from (
select
*
agg_function( my_field ) OVER( PARTITION BY other_field ) as agg_field
from sometable
) x
WHERE agg_field <condition>
就我而言,我有下一个查询:
SELECT * FROM (
SELECT *,
FIRST_VALUE( p.price ) over( PARTITION BY crate.app_period ORDER BY st.DEPTH ) AS first_price,
ROW_NUMBER() over( PARTITION BY crate.app_period ORDER BY st.DEPTH ) AS row_number
FROM st
LEFT JOIN price p ON <COND>
LEFT JOIN currency_rate crate ON <COND>
) p
WHERE p.row_number = 1 AND p.first_price IS NOT null
在这里,我仅从组中选择第一行,其中price IS NOT NULL