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