首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >根据other列中的条件选择值对- PostgreSQL

根据other列中的条件选择值对- PostgreSQL
EN

Stack Overflow用户
提问于 2020-03-29 01:05:18
回答 2查看 75关注 0票数 0

在过去的几天里,我一直在尝试解决一个问题,但我想不出解决方案是什么……

我有一个表,如下:

代码语言:javascript
运行
复制
+--------+-----------+-------+
| ShopID | ArticleID | Price |  
+--------+-----------+-------+
|      1 |         3 |   150 | 
|      1 |         2 |    80 |  
|      3 |         3 |   100 |  
|      4 |         2 |    95 |  
+--------+-----------+-------+

我想选择同一件商品价格较高的店铺I对。F.e.这应该看起来像这样:

代码语言:javascript
运行
复制
+----------+----------+---------+
| ShopID_1 | ShopID_2 |ArticleID|
+----------+----------+---------+
|        4 |        1 |       2 |
|        1 |        3 |       3 |
+----------+----------+---------+

..。显示ShopID 4中的第2条比ShopID 2中的更昂贵。

到目前为止,我的代码如下:

代码语言:javascript
运行
复制
SELECT ShopID AS ShopID_1, ShopID AS ShopID_2, ArticleID FROM table
WHERE table.ArticleID=table.ArticleID and table.Price > table.Price

但是它没有给出我想要的结果。

有人能帮我实现这个目标吗?非常感谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-29 02:20:24

这里的问题是计算每个组的前N个项目。

假设您在表sales中有以下数据。

代码语言:javascript
运行
复制
# select * from sales;
 shopid | articleid | price 
--------+-----------+-------
      1 |         2 |    80
      3 |         3 |   100
      4 |         2 |    95
      1 |         3 |   150
      5 |         3 |    50

使用以下查询,我们可以为每个ArticleId创建一个分区

代码语言:javascript
运行
复制
select 
  ArticleID, 
  ShopID, 
  Price, 
  row_number() over (partition by ArticleID order by Price desc) as Price_Rank from sales;

这将导致:

代码语言:javascript
运行
复制
 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选择前两项:

代码语言:javascript
运行
复制
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;

这将导致:

代码语言:javascript
运行
复制
 articleid | shopid | price 
-----------+--------+-------
         2 |      4 |    95
         2 |      1 |    80
         3 |      1 |   150
         3 |      3 |   100

最后,我们可以使用crosstab函数来获得预期的透视视图。

代码语言:javascript
运行
复制
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);

结果是:

代码语言:javascript
运行
复制
 ArticleID | ShopID_1 | ShopID_2 
-----------+----------+----------
         2 |        4 |        1
         3 |        1 |        3

注意:如果出现function crosstab(unknown) does not exist错误,您可能需要调用CREATE EXTENSION tablefunc;

票数 2
EN

Stack Overflow用户

发布于 2020-03-29 01:08:51

这个查询应该是有效的:

代码语言:javascript
运行
复制
SELECT t1.ShopID AS ShopID_1, t2.ShopID AS ShopID_2, t1.ArticleID
FROM <yourtable> t1 JOIN
     <yourtable> t2
     ON t1.ArticleID = t2.ArticleID AND t1.Price > t2.Price;

也就是说,您需要一个自联接和适当的表别名。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60904027

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档