获取每个产品的最新两行并获取价格和日期

Get the newest two line per product and get price and date

我做了一个查询,提取每个产品的两个最新行。每行显示 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

然后我得到: 产品编号,最新日期,第二新日期

可是价格怎么办呢?

不推荐我的方案。查看下面的 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

您可以使用 MAX()MIN()FIRST_VALUE() window 函数来实现:

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