【问题标题】:Select top 50 rows in sql server在sql server中选择前50行
【发布时间】:2017-07-28 07:46:15
【问题描述】:

我在 SQL Server 2014 中使用了以下 T-SQL 代码。

此代码生成 1000 行。但我只需要前 50 行(来自供应商列)。

在下面的代码中,如果我使用SELECT Top 50 s.[CusNo] Supplier,那么我不会得到想要的结果。

需要在下面的代码中进行哪些更改才能仅获得前 50 行(供应商列)而不对现有结果进行任何更改。

SELECT s.[CusNo] Supplier, 
RTRIM(CAST(s.[Customer] AS VARCHAR(50)) ) AS Name,
s.[ConcessionNo] Concession, 
RTRIM(CAST(s.[ConcessionName] AS VARCHAR(50)) ) AS ConcessionName,

sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) - 1) and convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) + 5) 
           then s.SELLINC else 0 end) ActualSales,

     sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) -1 /* On 14/Feb/2021 modify +6 to -1 */) and convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
           then s.SELLINC else 0 end) LastYrVariance,

     (sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) - 1) and convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) + 5) then s.SELLINC else 0 end))-

     (sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) -1 /* On 14/Feb/2021 modify +6 to -1 */) and convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */) then s.SELLINC else 0 end)) LastYrVariancePounds,

     (IsNull(sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) - 1) and convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) + 5) 
           then s.SELLINC else 0 end)-sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) -1 /* On 14/Feb/2021 modify +6 to -1 */) and convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
           then s.SELLINC else 0 end),0)/NullIf(sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) -1 /* On 14/Feb/2021 modify +6 to -1 */) and convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
           then s.SELLINC else 0 end),0))*100 LastYrVariancePercentage,


    sum(case when s.Date 
        BETWEEN         
             convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7  * 7, '19000107'), 120)
        AND        
             Convert(date, dateadd(wk, datediff(wk, 0, GETDATE()) - 1, 0) + 5)       
           then s.SELLINC else 0 end) YrToDateActual,


    sum(case when s.Date    
        BETWEEN  
           convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7  * 7, '19000107'), 120)
        AND
           convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
          then s.SELLINC else 0 end) LastYrToDateActual,


    (sum(case when s.Date 
     BETWEEN        
             convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7  * 7, '19000107'), 120)
        AND        
             Convert(date, dateadd(wk, datediff(wk, 0, GETDATE()) - 1, 0) + 5) 
           then s.SELLINC else 0 end))  

     -

    (sum(case when s.Date 
        BETWEEN  
           convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7  * 7, '19000107'), 120)
        AND
           convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
           then s.SELLINC else 0 end)) YrToDateVariancePounds,


    ((IsNull    
         (                   
            (sum(case when s.Date 
             BETWEEN        
             convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7  * 7, '19000107'), 120)
        AND        
             Convert(date, dateadd(wk, datediff(wk, 0, GETDATE()) - 1, 0) + 5)
           then s.SELLINC else 0 end))  

     -

    (sum(case when s.Date 
        BETWEEN  
           convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7  * 7, '19000107'), 120)
        AND
           convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
           then s.SELLINC else 0 end))

          ,0)

      ) 

      /

    (NullIf 
      (
         sum(case when s.Date 
            BETWEEN  
           convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7  * 7, '19000107'), 120)
        AND
           convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
           then s.SELLINC else 0 end)          

       ,0)))*100 LastYrToDateVariancePercentage

FROM [dbo].[CustomerReports] s
WHERE s.BRN = 1 or s.BRN = 2 or s.BRN = 3 or s.BRN = 4 or s.BRN = 5  or s.SELLINC is null or s.SELLINC = '0'
GROUP BY s.[CusNo], s.[Customer], s.ConcessionNo, s.ConcessionName
order by YrToDateActual desc  

当我在 SSRS 中运行此查询时,我得到以下结果(这是正确的)。但显示所有数据。

如果我使用 SELECT Top 50 s.[CusNo] Supplier(其余代码相同),那么我会得到以下内容,

因此,请查看两张图片中突出显示的部分。当我在 SQL 代码中添加前 50 名时,第一张图片中存在的几行(第三列)不会出现在第二张图片中。

【问题讨论】:

标签: sql sql-server sql-server-2008 tsql reporting-services


【解决方案1】:

试试这个:

With cte as (**your long query goes here**) 
Select Top(50) * From cte

【讨论】:

    【解决方案2】:

    查询中的排序顺序是YrToDateActual desc,因此TOP 50 为您提供了最高的50 个YrToDateActual 金额。您的 SSRS 报告按供应商编号和名称​​分组,但看起来并没有按这些列中的任何一个排序,所以我猜这些供应商的顺序在 SSRS 输出中有些随机。在这种情况下,我认为您永远无法获得原始 SSRS 输出的前 50 行。您可以做的最好的事情是也排序您的 SSRS 输出(例如按供应商编号),然后将此排序添加到您的查询中 (order by Supplier, YrToDateActual desc)。在查询中添加 TOP 50 会在前 50 个结果之后切断新排序的 SSRS 输出。

    【讨论】:

    • 谢谢,我现在就试试
    【解决方案3】:

    您希望在报告中看到什么?您想查看前 50 名供应商的总价值(例如实际 £ 总计),然后是所有特许权(根据您的第一个屏幕截图)吗?

    如果是这样,您需要按供应商总数对供应商进行排名,然后选择排名 50 或以下的供应商。

    这是一个非常简化的示例,可能会有所帮助。在此我使用 SUM() OVER() 而不是使用 GROUP BY 但这意味着您可能希望根据需要将 SELECT 更改为 SELECT DISTINCT,因为您将获得大量重复的行。显然它没有包含您冗长的案例陈述,但您应该能够轻松适应它。

    SELECT * FROM 
        (
            SELECT
                x.*
                , DENSE_RANK() OVER(ORDER BY SupplierTotal DESC) as SupplierRank
                , DENSE_RANK() OVER(PARTITION BY SupplierID ORDER BY ConcessionTotal DESC) as ConcessionRank
             FROM 
                (    SELECT DISTINCT
                SupplierID, ConcessionID, MyOtherRequiredColumns,
                SUM(myValue) OVER(PARTITION BY SupplierID) AS SupplierTotal,
                SUM(myValue) OVER(PARTITION BY SupplierID, ConcessionID) AS ConcessionTotal
                FROM MyTable
            ) x
        ) z
        WHERE SupplierRank <= 50
    

    这也会对可能有用的供应商的让步进行排名。

    您还必须更改汇总值的报告(例如,实际 £ 列中的 99,389)。不要对下面的行求和,而是将表达式更改为 =FIRST(Fields!SupplierTotal.Value)

    【讨论】:

      猜你喜欢
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-29
      • 2021-09-30
      • 1970-01-01
      相关资源
      最近更新 更多