【问题标题】:How can I query T-SQL to get "Top 10 'x' for each of 'y'如何查询 T-SQL 以获取每个 'y' 的“前 10 个'x'
【发布时间】:2013-06-25 18:06:12
【问题描述】:

好的,我找到了一些关于我正在尝试做的事情的密切参考,但是给出的示例和答案要么太简单以至于我无法推断,或者太复杂而无法掌握。我不是专业的 DBA,只是一个糟糕的网络技术,必须在 Visual Studio 2012 中为销售部门编写报告,所以请善待。

基本上,我需要在报表设计器中编写一个从 2 个表中提取的查询 - 'custextract' 和 'histextract'。结果是 30 个字段长(报告中需要所有字段,所以我很快学会了不要尝试在查询中分组)。

最终报告必须创建一个“客户联系页面”供销售人员带到现场 - 每个客户一个页面。上半部分是基本客户信息,完全来自客户表,下半部分是按产品线划分的销售历史信息表(期初至今、年初至今、去年等)。大约有 30 种可能的产品线,但大多数客户只从少数几个中购买。报告应该只返回 EACH Customer ORDERED BY year-to-date DESC 的 TOP(10) 行——如果有意义的话。到目前为止我的查询是:

SELECT custextract.*, histextract.*
FROM custextract 
INNER JOIN histextract 
        ON custextract.[cusx-cust-no] = histextract.[hisx-cust]
WHERE (custextract.[cusx-ecall-select] = 'Y')
ORDER BY histextract.[hisx-sales-ytd] DESC

明显的问题是,如果我在 SELECT 中包含 TOP(10),我只会得到前 10 个总数,而不是每个客户。我假设我需要选择一个 Count(histextract.[hisx-cust]) AS 号码,然后根据号码进行某种迭代循环,加入所有结果 - 但我完全不知道如何有效地完成这个。 Select, From, Where, Order by, Into 基本上是我查询能力的极限了。

我正在使用存储过程从作为 .csv 文件的 ISAM 数据库的提取中填充这两个表(我还没有弄清楚如何触发它,但那是以后的事了)。基本上只是一个 TRUNCATE 和 BULK INSERT 操作。但是,如果创建第三个表来保存排序和过滤的数据并使用该更新过程继续并创建所需的数据集(然后只需在报表设计器中使用第三个表)我愿意接受它 - 只是不知道怎么弄。

任何帮助将不胜感激。

【问题讨论】:

标签: sql-server tsql reporting-services


【解决方案1】:

没有加入,但我认为你可以得到这个想法

WITH OrderedOrders AS
(
    SELECT SalesOrderID, Customer,
    ROW_NUMBER() OVER (Customer BY SalesOrderID) AS RowNumber
    FROM Sales.SalesOrderHeader 
) 
SELECT SalesOrderID, Customer  
FROM OrderedOrders 
WHERE RowNumber <= 10;

ROW_NUMBER (Transact-SQL)

OP 需要的不仅仅是想法

WITH OrderedOrders AS
(
    SELECT custextract.[cusx-cust-no], histextract.[hisx-sales-ytd], 
           ROW_NUMBER() OVER (custextract.[cusx-cust-no] BY histextract.[hisx-sales-ytd] desc) AS RowNumber
    FROM custextract 
    INNER JOIN histextract 
        ON custextract.[cusx-cust-no] = histextract.[hisx-cust]
    WHERE (custextract.[cusx-ecall-select] = 'Y')
) 
SELECT OrderedOrders.[cusx-cust-no], OrderedOrders.[hisx-sales-ytd] 
FROM OrderedOrders 
WHERE RowNumber <= 10;

【讨论】:

  • 它必须有一个 CTE,因为您不能将 WHERE RowNumber 放在生成它的同一查询中(2012 版可能不同)
  • 什么是 CTE?这就是我感到困惑的原因 - 我很难使用一个表和 2 个字段来从 2 个表中选择所有字段并将它们连接在一起。这是我应该尝试的... WITH OrderedOrders AS ( SELECT , ROW_NUMBER() OVER (Customer BY SalesOrderID) AS RowNumber FROM Sales.SalesOrderHeader ) SELECT OrderedOrders., SecondTable.* FROM OrderedOrders INNER JOIN SecondTable ON OrderedOrders.Field1 = SecondTable.Field1 WHERE RowNumber
  • 好的,你们是如何获得格式化代码的 - 该评论只是扼杀了我实际尝试插入的内容。
  • WITH ( ) 是一个 CTE。转到msdn.microsoft.com/en-US 并在 TSQL CTE 上搜索
  • 没关系 - 显然在 2012 年,您必须拼出 PARTITION BY 和 ORDER BY 才能工作。现在就像一个魅力。再次感谢大家。
猜你喜欢
  • 1970-01-01
  • 2013-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多