【问题标题】:SQL Row Sum for some colums某些列的 SQL 行总和
【发布时间】:2012-06-22 17:23:44
【问题描述】:

我正在尝试开发一个 SQL 字段,它是除前两个之外的行的所有列的总和。下面是我的代码,它返回 MonthYear、Total、Sum1、Sum2 和 Sum3 列。我想要一个总计 Sum1、Sum2 和 Sum3 的 FinalSum。这将用于反检查 Total 列的准确性。有没有办法做到这一点?运行 Microsoft SQL Server 2005 - T-SQL

SELECT MonthYear,
            COUNT(*) AS Total,
            ISNULL(
                SUM(
                    CASE 
                    WHEN Status='Sum1'                  THEN 1
                    ELSE 0
                    END
                )
            ,0) AS [Sum1],
ISNULL(
                SUM(
                    CASE 
                    WHEN Status='Sum2'                  THEN 1
                    ELSE 0
                    END
                )
            ,0) AS [Sum2],
ISNULL(
                SUM(
                    CASE 
                    WHEN Status='Sum3'                  THEN 1
                    ELSE 0
                    END
                )
            ,0) AS [Sum3]
FROM tablename

GROUP BY
    MonthYear

【问题讨论】:

  • 您能否提供一些示例数据来更好地解释这一点?具有预期输出的相同样本数据将大大有助于解释您的目标。

标签: sql sql-server tsql sum


【解决方案1】:

您的查询缺少FROM。无论如何,一种方法是使用派生表:

SELECT *, [Sum1]+[Sum2]+[Sum3] AS TotalSum
FROM (Your Current Select Here) AS T

对于 SQL Server 2005+,您还可以使用 CTE:

;WITH CTE AS 
(
    Your Current Select Here
)
SELECT *, [Sum1]+[Sum2]+[Sum3] AS TotalSum
FROM CTE

【讨论】:

  • 有没有办法动态求和它们而不必手动写出每一列?我的实际查询有大约 15 列,最终可能会增长到 20 多列。
  • @steventnorris - 在这种情况下很难进行动态查询。另一方面,我想你可以做一个SUM 来获取你在其他列上的所有条件,而不是
  • @steventnorris ...我明白你的意思;您想要一种方法,以便名称以字符串“Sum”开头的所有字段字段自动添加在一起?我想知道这是怎么做到的;也许架构可以以某种方式使用
【解决方案2】:

好的 - 可能不是最优雅的方式(复制保存在这里on SqlFiddle

CREATE TABLE this_name 
(
    monthYear DateTime,
    status varchar(20), 
   );

INSERT INTO this_name
(monthYear, status)
VALUES
('01 jan 2012', 'Sum1'),
('01 jan 2012', 'Sum1'),
('01 feb 2012', 'Sum2'),
('01 feb 2012', 'Sum1'),
('01 apr 2012', 'Sum3'),
('01 jan 2013', 'Sum3'),
('01 jan 2013', 'Sum3'),
('01 jan 2012', 'Sum3')

;WITH myCTE (MonthYear,Total, Sum1, Sum2, Sum3)
AS
(
SELECT MonthYear,
       COUNT(*) AS Total,
       SUM(CASE WHEN ISNULL(Status,'X')='Sum1' THEN 1 ELSE 0 END) AS [Sum1],
       SUM(CASE WHEN ISNULL(Status,'X')='Sum2'THEN 1 ELSE 0 END ) AS [Sum2],
       SUM(CASE WHEN ISNULL(Status,'X')='Sum3' THEN 1 ELSE 0 END) AS [Sum3] 
FROM this_name
GROUP BY MonthYear
)   
SELECT 
  MonthYear,
  Total, 
  Sum1, 
  Sum2, 
  Sum3,
  (Sum1 + Sum2 + Sum3) [CountTotal]
FROM myCTE

另一种选择是这个([SQLFiddle];

SELECT MonthYear,
   COUNT(*) AS Total,
   SUM(CASE WHEN ISNULL(Status,'X')='Sum1' THEN 1 ELSE 0 END) AS [Sum1],
   SUM(CASE WHEN ISNULL(Status,'X')='Sum2'THEN 1 ELSE 0 END ) AS [Sum2],
   SUM(CASE WHEN ISNULL(Status,'X')='Sum3' THEN 1 ELSE 0 END) AS [Sum3], 

   SUM(CASE WHEN ISNULL(Status,'X')IN('Sum1','Sum2','Sum3') THEN 1 ELSE 0 END) AS [SumExtra]  
FROM this_name
GROUP BY MonthYear

【讨论】:

    【解决方案3】:
    declare @sum1 int, @sum2 int, @sum3 int
    declare @totalSum int = 0
    
    select @sum1 = ISNULL(SUM(CASE WHEN Status='Sum1' THEN 1 ELSE 0 END), 0)
    from tablename
    
    select @sum2 = ISNULL(SUM(CASE WHEN Status='Sum2' THEN 1 ELSE 0 END), 0)
    from tablename
    
    select @sum3 = ISNULL(SUM(CASE WHEN Status='Sum3' THEN 1 ELSE 0 END), 0)
    from tablename
    
    set @totalSum = @sum1 + @sum2 + @sum3
    
    SELECT MonthYear, COUNT(*) AS Total,
                ISNULL(SUM(
                        CASE 
                        WHEN Status='Sum1' THEN 1
                        ELSE 0
                        END
                    ), 0) AS [Sum1],
                ISNULL(SUM(
                        CASE 
                        WHEN Status='Sum2' THEN 1
                        ELSE 0
                        END), 0) AS [Sum2],
                ISNULL(SUM(
                        CASE 
                        WHEN Status='Sum3' THEN 1
                        ELSE 0
                        END), 0) AS [Sum3],
                @totalSum
    FROM tablename
    
    GROUP BY
        MonthYear
    

    【讨论】:

      【解决方案4】:

      使用临时表的一种方式

      CREATE TABLE #Table2
      (
          MonthYear VARCHAR(6) NOT NULL PRIMARY KEY,
          Total INT NOT NULL,
          Sum1 INT NOT NULL,
          Sum2 INT NOT NULL,
          Sum3 INT NOT NULL
      ) ;
      
      INSERT INTO #Table2
      SELECT
              MonthYear,
              COUNT(*) AS Total,
              SUM(CASE WHEN ISNULL(Status, '') = 'Sum1' THEN 1 ELSE 0 END),
              SUM(CASE WHEN ISNULL(Status, '') = 'Sum2' THEN 1 ELSE 0 END),
              SUM(CASE WHEN ISNULL(Status, '') = 'Sum3' THEN 1 ELSE 0 END)
      FROM tablename
      GROUP BY MonthYear ;
      
      SELECT *, Sum1Count + Sum2Count + Sum3Count AS FinalSum FROM #Table2 ;
      

      【讨论】:

        【解决方案5】:

        另一种重复计算的方法

        SELECT
                MonthYear,
                COUNT(*) AS Total,
                SUM(CASE WHEN ISNULL(Status, '') = 'Sum1' THEN 1 ELSE 0 END) AS [Sum1],
                SUM(CASE WHEN ISNULL(Status, '') = 'Sum2' THEN 1 ELSE 0 END) AS [Sum2],
                SUM(CASE WHEN ISNULL(Status, '') = 'Sum3' THEN 1 ELSE 0 END) AS [Sum3],
                SUM(CASE WHEN ISNULL(Status, '') = 'Sum1' THEN 1 ELSE 0 END) +
                SUM(CASE WHEN ISNULL(Status, '') = 'Sum2' THEN 1 ELSE 0 END) +
                SUM(CASE WHEN ISNULL(Status, '') = 'Sum3' THEN 1 ELSE 0 END) AS [FinalSum]
        FROM tablename
        GROUP BY MonthYear ;
        

        【讨论】:

          猜你喜欢
          • 2015-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-20
          • 1970-01-01
          • 2013-07-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多