Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 选择每年销售的前10种产品_Sql_Oracle_Db2 - Fatal编程技术网

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。几乎任何表达式都应该有效。我不知道使用函数调用有任何限制。