【问题标题】:add count for all rows ignoring group by in SQL在 SQL 中添加忽略分组依据的所有行的计数
【发布时间】:2016-10-20 16:25:40
【问题描述】:

我有一个查询,我已经处理了几天,感谢这个问题SQL SERVER T-SQL Calculate SubTotal and Total by group 我已经能够得到我的小计和我的总计。

当此数据返回到我的自定义应用程序(我无法控制的应用程序)时,它会按 ID 列对返回的数据进行排序,而忽略我的 ORDER BY 子句。

为了解决这个问题,我想在我的 TSQL 中添加一个哑计数,这样无论在哪个组中找到该行,计数器都会为找到的每一行增加 1。

我的代码如下。

select ID as ID,  EstRefNum as "Estimate No", 
        (case when GROUPING(Ordered) = 0 and
         GROUPING(Ref1) = 0 and
         GROUPING(ID) = 1
         then 
                case when Ref1 IS NULL
                then 'No BDM Sub Total'
                else Ref1 + ' Sub Total'
                end
         when GROUPING(Ordered) = 0 and
         GROUPING(Ref1) = 1 and
         GROUPING(ID) = 1
         then 
                CASE 
                WHEN Ordered = 0 THEN 'Not Ordered Sub Total'
                WHEN Ordered = 1 THEN 'Ordered Sub Total'
                WHEN Ordered = 2 THEN 'Superseded Sub Total'
                WHEN Ordered = 4 THEN 'Won/Convert Sub Total'
                WHEN Ordered = 5 THEN 'Lost Sub Total'
                WHEN Ordered IS NULL THEN 'None Sub Total'
                ELSE 'Unknown status code'
                END
         when GROUPING(Ordered) = 1 and
         GROUPING(Ref1) = 1 and
         GROUPING(ID) = 1
         then
                'Total'
         else 
                case 
                when Ref1 IS NULL
                then 'No BDM'
                else Ref1
                end
    end) as "Sales Rep",
    [mo].[EstimateDate] as "Estimate Date",
    [mo].[CustomerRef] as "Customer",
    [mo].[JobDescription] as "Title",
    cast(Format([mo].[OtherTotal], 'N', 'en-us') as varchar(30)) as "Estimate total",
    [mo].[TotalTotal] as "Sales",
    [mo].[PaperSubTot] + [mo].[OriginMatSubTot] + [mo].[OtherMatSubTotal] + [mo].[OutworkSubtot] as "Direct Costs",
    [mo].[TotalTotal] - ([mo].[PaperSubTot] + [mo].[OriginMatSubTot] + [mo].[OtherMatSubTotal] + [mo].[OutworkSubtot]) as "Value Added",
    ([mo].[OriginLabLabSubTot] + [mo].[PrintingSubTotal] + [mo].[FinishingSubTotal]) as "Overheads",
    ([mo].[TotalTotal] - ([mo].[PaperSubTot] + [mo].[OriginMatSubTot] + [mo].[OtherMatSubTotal] + [mo].[OutworkSubtot])) - ([mo].[OriginLabLabSubTot] + [mo].[PrintingSubTotal] + [mo].[FinishingSubTotal]) as "Profit",
    sum(TotalTotal) as SubTotal,
        CASE 
        WHEN [mo].[OtherTotal] = 0.000000 THEN '0.00'
        WHEN [mo].[OtherTotal] = .00 THEN '0.00'
        WHEN [mo].[OtherTotal] = 0.00 THEN '0.00'
        ELSE LTRIM(Str(CAST([mo].[OtherTotal] as decimal(18,2)), 25, 2))
        END AS 'CASE EST TOTAL',
        CASE 
        WHEN Ordered = 0 THEN 'Not Ordered'
        WHEN Ordered = 1 THEN 'Ordered'
        WHEN Ordered = 2 THEN 'Superseded'
        WHEN Ordered = 4 THEN 'Won/Convert'
        WHEN Ordered = 5 THEN 'Lost'
        WHEN Ordered IS NULL THEN 'None'
        ELSE 'Unknown status code'
        END AS 'Estimate Status'

From [dbo].[MainEstimateDetails] [mo] WITH (NOLOCK)

WHERE
 [mo].[Ref1] LIKE 'STAFF MEMBER NAME'

 group by grouping sets((Ordered, Ref1, ID, EstRefNum,EstimateDate, CustomerRef, JobDescription, OtherTotal, TotalTotal, PaperSubTot, OriginMatSubTot, OtherMatSubTotal, OutworkSubtot, OriginLabLabSubTot, PrintingSubTotal, FinishingSubTotal),
                   (Ordered, Ref1),
                   ()                      
                  )

 order by 'Estimate Status' Desc;

它返回数据如下。

What i get

我想要的只是左侧的计数如下

What i want

如何在忽略 group by 命令的情况下获得返回的行数?我已经成功地获得了每个组中的项目数量,这些数量很接近但不是我想要的。我只是不知道如何操作一个变量,以便在通过 select 语句创建的数据库的每个循环中将其递增 1。

我找到的问题和答案与我所需要的很接近,但似乎没有什么是灵丹妙药。

谢谢 院长

【问题讨论】:

  • 您只需要 ROW_NUMBER 个。您只需要决定将哪一列用作订单。 msdn.microsoft.com/en-us/library/ms186734.aspx 您拥有的 order by 子句毫无意义,因为它是按字符串文字排序,而不是按列别名排序。这意味着您将获得一些订单,但您不知道是什么。你也可以考虑不要把 NOLOCK 撒得到处都是。它比大多数人意识到的要险恶得多。 blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere
  • 感谢您提供关于 NO LOCK 的信息。那部分不是我做的,而是创建用于与数据库交互的默认基本代码的人做的。我可能会删除它,看看结果如何!

标签: sql sql-server tsql


【解决方案1】:

正如评论所说,您只需添加如下所示的 ROW_NUMBER 列。它将为每一行增加一个整数。

select ID as ID,  EstRefNum as "Estimate No", 
        (case when GROUPING(Ordered) = 0 and
         GROUPING(Ref1) = 0 and
         GROUPING(ID) = 1
         then 
                case when Ref1 IS NULL
                then 'No BDM Sub Total'
                else Ref1 + ' Sub Total'
                end
         when GROUPING(Ordered) = 0 and
         GROUPING(Ref1) = 1 and
         GROUPING(ID) = 1
         then 
                CASE 
                WHEN Ordered = 0 THEN 'Not Ordered Sub Total'
                WHEN Ordered = 1 THEN 'Ordered Sub Total'
                WHEN Ordered = 2 THEN 'Superseded Sub Total'
                WHEN Ordered = 4 THEN 'Won/Convert Sub Total'
                WHEN Ordered = 5 THEN 'Lost Sub Total'
                WHEN Ordered IS NULL THEN 'None Sub Total'
                ELSE 'Unknown status code'
                END
         when GROUPING(Ordered) = 1 and
         GROUPING(Ref1) = 1 and
         GROUPING(ID) = 1
         then
                'Total'
         else 
                case 
                when Ref1 IS NULL
                then 'No BDM'
                else Ref1
                end
    end) as "Sales Rep",
    [mo].[EstimateDate] as "Estimate Date",
    [mo].[CustomerRef] as "Customer",
    [mo].[JobDescription] as "Title",
    cast(Format([mo].[OtherTotal], 'N', 'en-us') as varchar(30)) as "Estimate total",
    [mo].[TotalTotal] as "Sales",
    [mo].[PaperSubTot] + [mo].[OriginMatSubTot] + [mo].[OtherMatSubTotal] + [mo].[OutworkSubtot] as "Direct Costs",
    [mo].[TotalTotal] - ([mo].[PaperSubTot] + [mo].[OriginMatSubTot] + [mo].[OtherMatSubTotal] + [mo].[OutworkSubtot]) as "Value Added",
    ([mo].[OriginLabLabSubTot] + [mo].[PrintingSubTotal] + [mo].[FinishingSubTotal]) as "Overheads",
    ([mo].[TotalTotal] - ([mo].[PaperSubTot] + [mo].[OriginMatSubTot] + [mo].[OtherMatSubTotal] + [mo].[OutworkSubtot])) - ([mo].[OriginLabLabSubTot] + [mo].[PrintingSubTotal] + [mo].[FinishingSubTotal]) as "Profit",
    sum(TotalTotal) as SubTotal,
        CASE 
        WHEN [mo].[OtherTotal] = 0.000000 THEN '0.00'
        WHEN [mo].[OtherTotal] = .00 THEN '0.00'
        WHEN [mo].[OtherTotal] = 0.00 THEN '0.00'
        ELSE LTRIM(Str(CAST([mo].[OtherTotal] as decimal(18,2)), 25, 2))
        END AS 'CASE EST TOTAL',
        CASE 
        WHEN Ordered = 0 THEN 'Not Ordered'
        WHEN Ordered = 1 THEN 'Ordered'
        WHEN Ordered = 2 THEN 'Superseded'
        WHEN Ordered = 4 THEN 'Won/Convert'
        WHEN Ordered = 5 THEN 'Lost'
        WHEN Ordered IS NULL THEN 'None'
        ELSE 'Unknown status code'
        END AS 'Estimate Status',

ROW_NUMBER() OVER(ORDER BY CASE 
        WHEN Ordered = 0 THEN 'Not Ordered'
        WHEN Ordered = 1 THEN 'Ordered'
        WHEN Ordered = 2 THEN 'Superseded'
        WHEN Ordered = 4 THEN 'Won/Convert'
        WHEN Ordered = 5 THEN 'Lost'
        WHEN Ordered IS NULL THEN 'None'
        ELSE 'Unknown status code'
        END) AS RowID
From [dbo].[MainEstimateDetails] [mo] WITH (NOLOCK)

WHERE
 [mo].[Ref1] LIKE 'STAFF MEMBER NAME'

 group by grouping sets((Ordered, Ref1, ID, EstRefNum,EstimateDate, CustomerRef, JobDescription, OtherTotal, TotalTotal, PaperSubTot, OriginMatSubTot, OtherMatSubTotal, OutworkSubtot, OriginLabLabSubTot, PrintingSubTotal, FinishingSubTotal),
                   (Ordered, Ref1),
                   ()                      
                  )

 order by 'Estimate Status' Desc;

【讨论】:

  • 绝对完美,谢谢。这正是我一直在寻找的一天中最好的部分!现在要弄清楚如何将最终总数作为最终金额而不是第一个金额,我已设置:D
猜你喜欢
  • 1970-01-01
  • 2019-04-24
  • 2011-06-09
  • 1970-01-01
  • 2017-08-19
  • 2019-10-05
  • 2021-04-11
  • 1970-01-01
  • 2015-11-26
相关资源
最近更新 更多