在sql server中选择前50行

时间:2017-03-07 22:25:56

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

我有以下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中运行此查询时,我得到以下结果(这是正确的)。但显示所有数据。

enter image description here

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

enter image description here

所以请看两张图片中突出显示的部分。当我在SQL代码中添加Top 50时,第一个图像中出现的几行(第3列)在第二个图像中不存在。

3 个答案:

答案 0 :(得分:0)

试试这个:

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您希望在报告中看到什么?您是否希望根据其总价值(例如实际£总计)和所有优惠(根据您的第一个屏幕截图)查看前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)