Sql 选择每年销售的前10种产品
我有两张桌子:Sql 选择每年销售的前10种产品,sql,oracle,db2,Sql,Oracle,Db2,我有两张桌子: Sales columns: (Sales_id, Date , Customer_id, Product_id, Purchase_amount): Product columns: ( Product_id, Product_Name, Brand_id,Brand_name) 我必须写一个查询来查找每年销售的前10种产品。我现在的问题是: WITH PH AS (SELECT P.Product_Name, LEFT(S.Date,4) "SYEAR&q
Sales
columns: (Sales_id, Date , Customer_id, Product_id, Purchase_amount):
Product
columns: ( Product_id, Product_Name, Brand_id,Brand_name)
我必须写一个查询来查找每年销售的前10种产品。我现在的问题是:
WITH PH AS
(SELECT P.Product_Name, LEFT(S.Date,4) "SYEAR", COUNT(S.Product_id) "Product Count"
FROM Sales S LEFT JOIN Product P
ON S.Product_Id=P.Product_Id
GROUP BY P.Product_Name, LEFT(S.Date,4)
SELECT P.Product_Name, "SYEAR", "Product_Count"
FROM (SELECT P.Product_Name, "SYEAR", "Product_Count",
RANK OVER (PARTITION BY "SYEAR" ORDER BY "Product_Count" DESC) "TEMP"
)
WHERE "TEMP"<=10
这似乎不是最优化的查询。你能帮我吗?是否有替代版本以获得所需结果
注释
重复该代码的主要原因是允许按年份分组。给定表中没有该年的字段。
日期格式为:YYYYMMDD示例:20200630
任何帮助都将不胜感激。提前感谢您可以将窗口功能与聚合结合起来:
SELECT PY.*
FROM (SELECT P.Product_Name, LEFT(S.Date,4) AS YEAR, COUNT(*) AS CNT,
RANK() OVER (PARTITION BY LEFT(S.Date, 4) ORDER BY COUNT(*) DESC) AS SEQNUM
FROM Sales S LEFT JOIN
Product P
ON S.Product_Id = P.Product_Id
GROUP BY P.Product_Name, LEFT(S.Date, 4)
) PY
WHERE SEQNUM <= 10;
从性能角度来看,这可能会生成一个与查询非常类似的执行计划。不过,操作起来更简单。您可以将窗口函数与聚合组合在一起:
SELECT PY.*
FROM (SELECT P.Product_Name, LEFT(S.Date,4) AS YEAR, COUNT(*) AS CNT,
RANK() OVER (PARTITION BY LEFT(S.Date, 4) ORDER BY COUNT(*) DESC) AS SEQNUM
FROM Sales S LEFT JOIN
Product P
ON S.Product_Id = P.Product_Id
GROUP BY P.Product_Name, LEFT(S.Date, 4)
) PY
WHERE SEQNUM <= 10;
从性能角度来看,这可能会生成一个与查询非常类似的执行计划。不过,执行起来更简单。非常感谢您提供的解决方案。虽然我认为“分区依据”不能与用户定义的字段一起工作。@Sharon。几乎任何表达式都应该有效。我不知道使用函数调用有任何限制。非常感谢您提供的解决方案。虽然我认为“分区依据”不能与用户定义的字段一起工作。@Sharon。几乎任何表达式都应该有效。我不知道使用函数调用有任何限制。