Postgres 获得单个供应商的第一个和最后一个版本
Postgres get first and last version for individual vendor
我有 RFQ(报价请求)和供应商投标金额与版本的映射 table。
Table :
id rfq_id(FK) vendor_id(FK) amount version
-----------------------------------------------
1 1 1 100 1
2 1 1 90 2
3 1 1 80 3
4 1 2 50 1
5 1 7 500 1
6 1 7 495 2
7 1 7 500 3
8 1 7 525 4
9 1 7 450 5
10 1 7 430 6
11 2 1 200 1
12 2 2 300 1
13 2 2 350 2
14 2 3 40 1
15 3 4 70 1
在上面 table 中,我想分析供应商对特定 rfq_id
的第一次和最后一次出价。
rfq_id=1 的预期输出:
vendor_id first_bid last_bid
---------------------------------
1 100 80
2 50 50
7 500 430
从我开始了解window
和partition
。所以我尝试了以下查询。
SELECT
vendor_id,
version,
amount,
first_value(amount) over w as first_bid,
last_value(amount) over w as last_bid,
row_number() over w as rn
FROM
rfq_vendor_version_mapping
where
rfq_id=1
WINDOW w AS (PARTITION BY vendor_id order by version)
ORDER by vendor_id;
通过上述查询,每个供应商的最大值 rn
是我的输出。
您必须 GROUP BY vendor_id
因为每个 vendor_id
只需要一行:
SELECT
vendor_id,
MAX(CASE WHEN rn = 1 THEN amount END) AS first_bid,
MAX(CASE WHEN rn2 = 1 THEN amount END) AS last_bid
FROM (
SELECT
vendor_id,
version,
amount,
row_number() over (PARTITION BY vendor_id order BY version) as rn,
row_number() over (PARTITION BY vendor_id order BY version DESC) as rn2
FROM
rfq_vendor_version_mapping
WHERE
rfq_id=1) AS t
GROUP BY vendor_id
ORDER by vendor_id;
查询使用条件聚合 以提取与第一个和最后一个出价相对应的 amount
个值。
Window 函数 add 列到所有现有行,而不是将输入行分组到单个输出行中。由于您只对出价感兴趣,因此请在感兴趣的字段上使用 DISTINCT
子句。
请注意,WINDOW
定义需要 frame clause 以确保考虑分区中的所有行。默认情况下,分区中的帧(计算中使用的行)从分区的开头运行到当前行。因此,last_value()
window函数总是returns当前行的值;使用UNBOUNDED PRECEDING TO UNBOUNDED FOLLOWING
的框架将框架扩展到整个分区。
SELECT <b>DISTINCT</b>
vendor_id,
<strike>version,</strike>
<strike>amount,</strike>
first_value(amount) OVER w AS first_bid,
last_value(amount) OVER w AS last_bid
<strike> row_number() over w as rn</strike>
FROM
rfq_vendor_version_mapping
WHERE rfq_id = 1
WINDOW w AS (PARTITION BY vendor_id ORDER BY version
<b>ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING</b>)
ORDER BY vendor_id;
如果没有 ORDER BY
,OLAP 函数默认为 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
,但如果有 ORDER BY
,这将更改为 ROW UNBOUNDED PRECEDING
。
你很接近,但你需要两个不同的windows:
select vendor_id, amount as first_bid, last_bid
from
(
SELECT
vendor_id,
version,
amount,
last_value(amount) -- highest version's bid
over (PARTITION BY vendor_id
order by version
rows between unbiunded preceding and unbounded following) as last_bid,
row_number()
over (PARTITION BY vendor_id
order by version) as rn
FROM
rfq_vendor_version_mapping
where
rfq_id=1
) as dt
where rn = 1 -- row with first version/bid
ORDER by vendor_id;
我有 RFQ(报价请求)和供应商投标金额与版本的映射 table。
Table :
id rfq_id(FK) vendor_id(FK) amount version
-----------------------------------------------
1 1 1 100 1
2 1 1 90 2
3 1 1 80 3
4 1 2 50 1
5 1 7 500 1
6 1 7 495 2
7 1 7 500 3
8 1 7 525 4
9 1 7 450 5
10 1 7 430 6
11 2 1 200 1
12 2 2 300 1
13 2 2 350 2
14 2 3 40 1
15 3 4 70 1
在上面 table 中,我想分析供应商对特定 rfq_id
的第一次和最后一次出价。
rfq_id=1 的预期输出:
vendor_id first_bid last_bid
---------------------------------
1 100 80
2 50 50
7 500 430
从window
和partition
。所以我尝试了以下查询。
SELECT
vendor_id,
version,
amount,
first_value(amount) over w as first_bid,
last_value(amount) over w as last_bid,
row_number() over w as rn
FROM
rfq_vendor_version_mapping
where
rfq_id=1
WINDOW w AS (PARTITION BY vendor_id order by version)
ORDER by vendor_id;
通过上述查询,每个供应商的最大值 rn
是我的输出。
您必须 GROUP BY vendor_id
因为每个 vendor_id
只需要一行:
SELECT
vendor_id,
MAX(CASE WHEN rn = 1 THEN amount END) AS first_bid,
MAX(CASE WHEN rn2 = 1 THEN amount END) AS last_bid
FROM (
SELECT
vendor_id,
version,
amount,
row_number() over (PARTITION BY vendor_id order BY version) as rn,
row_number() over (PARTITION BY vendor_id order BY version DESC) as rn2
FROM
rfq_vendor_version_mapping
WHERE
rfq_id=1) AS t
GROUP BY vendor_id
ORDER by vendor_id;
查询使用条件聚合 以提取与第一个和最后一个出价相对应的 amount
个值。
Window 函数 add 列到所有现有行,而不是将输入行分组到单个输出行中。由于您只对出价感兴趣,因此请在感兴趣的字段上使用 DISTINCT
子句。
请注意,WINDOW
定义需要 frame clause 以确保考虑分区中的所有行。默认情况下,分区中的帧(计算中使用的行)从分区的开头运行到当前行。因此,last_value()
window函数总是returns当前行的值;使用UNBOUNDED PRECEDING TO UNBOUNDED FOLLOWING
的框架将框架扩展到整个分区。
SELECT <b>DISTINCT</b>
vendor_id,
<strike>version,</strike>
<strike>amount,</strike>
first_value(amount) OVER w AS first_bid,
last_value(amount) OVER w AS last_bid
<strike> row_number() over w as rn</strike>
FROM
rfq_vendor_version_mapping
WHERE rfq_id = 1
WINDOW w AS (PARTITION BY vendor_id ORDER BY version
<b>ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING</b>)
ORDER BY vendor_id;
如果没有 ORDER BY
,OLAP 函数默认为 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
,但如果有 ORDER BY
,这将更改为 ROW UNBOUNDED PRECEDING
。
你很接近,但你需要两个不同的windows:
select vendor_id, amount as first_bid, last_bid
from
(
SELECT
vendor_id,
version,
amount,
last_value(amount) -- highest version's bid
over (PARTITION BY vendor_id
order by version
rows between unbiunded preceding and unbounded following) as last_bid,
row_number()
over (PARTITION BY vendor_id
order by version) as rn
FROM
rfq_vendor_version_mapping
where
rfq_id=1
) as dt
where rn = 1 -- row with first version/bid
ORDER by vendor_id;