挑战Northwind数据库的PostgreSQL SELECT陈述式(需要说明-初学者)

8dtrkrch  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(1)|浏览(98)

我大约一个月前开始学习SQL,我爸爸一直在给我练习查询,让我用Northwind数据库来运行,以帮助练习DML。他给我的最新一个查询如下:-- Return Month、Product name、SalesForMonth,以取得1997年每个--月份最畅销的产品。(请参阅下面建立上述查询的问题)
(我目前正在pgAdmin 4上使用PostgreSQL)
我能够提出以下查询,该查询仅返回一个月的所需列和正确信息:

SELECT CAST( EXTRACT( MONTH FROM o.orderdate) AS integer) AS Month, p.productname, 
    ROUND(CAST(SUM(od.quantity * od.unitprice) AS numeric), 2) SalesForMonth
FROM order_details od 
INNER JOIN orders o ON od.orderid = o.orderid
INNER JOIN products p ON od.productid = p.productid
WHERE EXTRACT( YEAR FROM o.orderdate) = 1997 AND EXTRACT( MONTH FROM o.orderdate) = 1
GROUP BY Month, p.productname
ORDER BY salesformonth DESC
LIMIT 1

通过创建12个这样的查询,并将WHERE语句中的extract-month位从1更改为12,然后将它们联合在一起,我可以产生所需的结果,但我想知道是否有一种更简单的方法,可以只使用一个查询来显示相同的结果。
注意:我最初的想法是它与子查询有关,因为你实际上试图做的是显示MAX(SUM(值)),但实际上不能这样做,因为你不能嵌套聚合函数。

mspsb9vt

mspsb9vt1#

您的查询为您提供了给定月份最畅销的产品,并且您希望同时为多个月份提供相同的逻辑。
从现有的工作查询开始,一种简单的方法是使用WITH TIES

SELECT DATE_TRUNC('month', o.orderdate) DateMonth, 
    p.productname, 
    ROUND(CAST(SUM(od.quantity * od.unitprice) AS numeric), 2) SalesForMonth
FROM order_details od 
INNER JOIN orders o ON od.orderid = o.orderid
INNER JOIN products p ON od.productid = p.productid
WHERE o.orderdate >= DATE '1997-01-01' AND o.orderdate < DATE '1998-01-01'  
GROUP BY DateMonth, p.productname
ORDER BY RANK() OVER(
    PARTITION BY DATE_TRUNC('month', o.orderdate) 
    ORDER BY SUM(od.quantity * od.unitprice) DESC
)
FETCH FIRST ROW WITH TIES

我们也可以使用DISTINCT ON

SELECT DISTINCT ON (DateMonth)
    DATE_TRUNC('month', o.orderdate) DateMonth, 
    p.productname, 
    ROUND(CAST(SUM(od.quantity * od.unitprice) AS numeric), 2) SalesForMonth
FROM order_details od 
INNER JOIN orders o ON od.orderid = o.orderid
INNER JOIN products p ON od.productid = p.productid
WHERE o.orderdate >= DATE '1997-01-01' AND o.orderdate < DATE '1998-01-01'  
GROUP BY DateMonth, p.productname    
ORDER BY DateMonth, SalesForMonth DESC

相关问题