sql - 根据其他列中的条件选择值对 - PostgreSQL
问题描述
过去几天我一直在尝试解决一个问题,但无法弄清楚解决方案是什么......
我有一张如下表:
+--------+-----------+-------+
| ShopID | ArticleID | Price |
+--------+-----------+-------+
| 1 | 3 | 150 |
| 1 | 2 | 80 |
| 3 | 3 | 100 |
| 4 | 2 | 95 |
+--------+-----------+-------+
并且我想选择同一篇文章价格更高的商店ID对。Fe 这应该是这样的:
+----------+----------+---------+
| ShopID_1 | ShopID_2 |ArticleID|
+----------+----------+---------+
| 4 | 1 | 2 |
| 1 | 3 | 3 |
+----------+----------+---------+
...表明第 2 条在 ShopID 4 中比在 ShopID 2 中更贵。等等
到目前为止,我的代码如下所示:
SELECT ShopID AS ShopID_1, ShopID AS ShopID_2, ArticleID FROM table
WHERE table.ArticleID=table.ArticleID and table.Price > table.Price
但它没有给出我正在寻找的结果。
任何人都可以帮助我实现这个目标吗?非常感谢你。
解决方案
这里的问题是关于计算每个组的前 N 个项目。
假设您有以下数据,在表中sales
。
# select * from sales;
shopid | articleid | price
--------+-----------+-------
1 | 2 | 80
3 | 3 | 100
4 | 2 | 95
1 | 3 | 150
5 | 3 | 50
通过以下查询,我们可以为每个ArticleId
select
ArticleID,
ShopID,
Price,
row_number() over (partition by ArticleID order by Price desc) as Price_Rank from sales;
这将导致:
articleid | shopid | price | price_rank
-----------+--------+-------+------------
2 | 4 | 95 | 1
2 | 1 | 80 | 2
3 | 1 | 150 | 1
3 | 3 | 100 | 2
3 | 5 | 50 | 3
然后我们只需为每个 AritcleId 选择 Top 2 项:
select
ArticleID,
ShopID,
Price
from (
select
ArticleID,
ShopID,
Price,
row_number() over (partition by ArticleID order by Price desc) as Price_Rank
from sales) sales_rank
where Price_Rank <= 2;
这将导致:
articleid | shopid | price
-----------+--------+-------
2 | 4 | 95
2 | 1 | 80
3 | 1 | 150
3 | 3 | 100
最后,我们可以使用crosstab
函数来获得预期的枢轴视图。
select *
from crosstab(
'select
ArticleID,
ShopID,
ShopID
from (
select
ArticleID,
ShopID,
Price,
row_number() over (partition by ArticleID order by Price desc) as Price_Rank
from sales) sales_rank
where Price_Rank <= 2')
AS sales_top_2("ArticleID" INT, "ShopID_1" INT, "ShopID_2" INT);
结果:
ArticleID | ShopID_1 | ShopID_2
-----------+----------+----------
2 | 4 | 1
3 | 1 | 3
CREATE EXTENSION tablefunc;
注意:如果遇到错误,您可能需要致电function crosstab(unknown) does not exist
。
推荐阅读
- flutter - 如何在单独的文件中使用大量的“import”?
- javascript - 单击链接时,我的 jQuery Nav 菜单视图会跳转
- javascript - 在 NextJS 中设置 MDX 组件道具
- java - 创建一个包含 4 位数字的所有可能组合的字符串 str = "0000", "0001", ..."9999"; - 爪哇
- python - python vscoder中数学的工作是什么
- r - 从R中的数据表中获取数据
- javascript - 如何通过 NextJS API 路由使用 Firebase 云消息传递
- python - 在 DataFrame 中拆分字符串并仅保留某些部分
- java - 将 Java/Kotlin 对象发送到 RSocket 路由
- arrays - 标识循环 - 此循环不变量可能不会由循环维护