【问题标题】:Get the newest two line per product and get price and date获取每个产品最新的两条线并获取价格和日期
【发布时间】:2021-12-04 16:41:42
【问题描述】:

我做了一个查询,提取每个产品的两个最新行。每行显示 id、productnumber、pricechangedate、price。

Id Prod number Date Price Rank Order
71582 0071807993 2021-10-15 18:06:22 220.79 1
60533 0071807993 2021-10-15 13:22:46 220.79 2

是否有可能如何连接这些行来显示:

Prod number Newest Date Newest Price Second Newest Date Second Newest Price
0071807993 2021-10-15 18:06:22 220.79 2021-10-15 13:22:46 220.79

我的查询如下所示:

select * from
(
SELECT
    id,
    prodnumb,
    collectdate, price,row_number() over(partition by prodnumb order by id desc) as rn
FROM product
)A where rn <3

我发现我可以这样做:

select prodnumb, max(collectdate), min(collectdate) 
from
(
SELECT
    id,
    prodnumb,
    collectdate, price,row_number() over(partition by prodnumborder by id desc) as rn
FROM product
-- WHERE deviceId > 0
)A where rn <3
group by prodnumb

然后我得到: prodnumber,最新日期,第二个最新日期

但是我应该如何处理价格?

不推荐我的解决方案。查看下面的 forpas 解决方案以获得更好的解决方案:

select p.prodnumb, f.collectdate, f.price, s.collectdate, s.price
from product p

left join (

    select * from
    (
    SELECT
        id,
        prodnumb,
        collectdate, price,row_number() over(partition by prodnumb order by id desc) as rn
    FROM product
    -- WHERE deviceId > 0
    )A where rn = 1
    
    )f on f.prodnumb = p.prodnumb



left join (

    select * from
    (
    SELECT
        id,
        prodnumb,
        collectdate, price,row_number() over(partition by prodnumb order by id desc) as rn
    FROM product
    -- WHERE deviceId > 0
    )A where rn = 2

    )s on s.prodnumb = p.prodnumb
    
group by p.prodnumb

【问题讨论】:

    标签: sql mariadb window-functions conditional-aggregation


    【解决方案1】:

    您可以使用MAX()MIN()FIRST_VALUE() 窗口函数来做到这一点:

    SELECT DISTINCT prodnumb,
           MAX(collectdate) OVER (PARTITION BY prodnumb) NewestDate,
           FIRST_VALUE(price) OVER (PARTITION BY prodnumb ORDER BY collectdate DESC) NewestPrice,
           MIN(collectdate) OVER (PARTITION BY prodnumb) SecondNewestDate,
           FIRST_VALUE(price) OVER (PARTITION BY prodnumb ORDER BY collectdate) SecondNewestPrice
    FROM (
      SELECT prodnumb, collectdate, price,
             ROW_NUMBER() OVER (PARTITION BY prodnumb ORDER BY id DESC) rn
      FROM product
    ) t 
    WHERE rn < 3;
    

    或者使用条件聚合:

    SELECT prodnumb,
           MAX(CASE WHEN rn = 1 THEN collectdate END) NewestDate,
           MAX(CASE WHEN rn = 1 THEN price END) NewestPrice,
           MAX(CASE WHEN rn = 2 THEN collectdate END) SecondNewestDate,
           MAX(CASE WHEN rn = 2 THEN price END) SecondNewestPrice
    FROM (
      SELECT prodnumb, collectdate, price,
             ROW_NUMBER() OVER (PARTITION BY prodnumb ORDER BY id DESC) rn
      FROM product
    ) t 
    WHERE rn < 3
    GROUP BY prodnumb;
    

    您在ROW_NUMBER() 的查询中使用了ORDER BY id DESC,我将其保留在我的代码中,但也许您应该更改为ORDER BY collectdate DESC

    【讨论】:

    • 谢谢@forpas!我想我最终解决了,但我的比你慢得多(花了更长的时间)。
    猜你喜欢
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    • 2020-03-05
    • 1970-01-01
    • 2017-12-05
    • 1970-01-01
    相关资源
    最近更新 更多