【问题标题】:Get sum of different column of different table in a single query在单个查询中获取不同表的不同列的总和
【发布时间】:2013-12-30 21:54:51
【问题描述】:

我通过这个查询得到错误的总和答案 - 有人知道我做错了什么吗?我得到第一个总和两次,第二个总和是实际值的 3 倍,依此类推。

SELECT ogr.Region_ID,
       ogr.Region_Name,
       Sum(daf.Total_Allowance) AS DailyAllowance,
       Sum(naf.Total_Allowance) AS NightAllowance,
       Sum(caf.Total_Amount) AS AdvanceCash,
       Sum(att.Extra_Amounts) AS OverTime,
       Sum(eef.Total_Amount) AS EmployeeExpense,
       Sum(maf.Total_Amount) AS MobileAllowance,
       Sum(odf.On_Week_Amount) AS OnWeek,
       Sum(emp.Salary) AS EmployeeSalary
FROM   ORG_Region ogr
       LEFT OUTER JOIN DailyAllowanceForm AS daf
                    ON daf.Region_ID = ogr.Region_ID
       LEFT OUTER JOIN NightAllowance AS naf
                    ON naf.Region_ID = ogr.Region_ID
       LEFT OUTER JOIN CashAdvance AS caf
                    ON caf.Region_ID = ogr.Region_ID
       LEFT OUTER JOIN Attandence AS att
                    ON att.Region_ID = ogr.Region_ID
       LEFT OUTER JOIN EmployeeExpensesForm AS eef
                    ON eef.Region_ID = ogr.Region_ID
       LEFT OUTER JOIN MobileAllowance AS maf
                    ON maf.Region_ID = ogr.Region_ID
       LEFT OUTER JOIN OnDutyForms AS odf
                    ON odf.Region_ID = ogr.Region_ID
       LEFT OUTER JOIN Employee AS emp
                    ON emp.Region = ogr.Region_ID
GROUP  BY ogr.Region_ID,ogr.Region_Name

【问题讨论】:

  • 你为什么不在这里使用inner join?您是否还在这些表中使用 enabledisable 标志?
  • 能否展示样本数据和样本结果?
  • 如果 naf 有 3 行,无论在哪个区域,它都会将所有三行相加并在该区域前面显示总和。这是由于左外连接

标签: sql sql-server sql-server-2008 select group-by


【解决方案1】:

问题是您从重复的行中添加:

表A

Aid, Avalue
1, 7
2, 3

表B

Aid
1
1
2
2
2

你会得到像 14 和 9 这样的数字 因为你多次数 B。

在子查询中拆分大选择,例如在 Prashant 答案中

【讨论】:

    【解决方案2】:

    尝试使用INNER JOIN

    SELECT ogr.Region_ID,
           ogr.Region_Name,
           Sum(daf.Total_Allowance) AS DailyAllowance,
           Sum(naf.Total_Allowance) AS NightAllowance,
           Sum(caf.Total_Amount) AS AdvanceCash,
           Sum(att.Extra_Amounts) AS OverTime,
           Sum(eef.Total_Amount) AS EmployeeExpense,
           Sum(maf.Total_Amount) AS MobileAllowance,
           Sum(odf.On_Week_Amount) AS OnWeek,
           Sum(emp.Salary) AS EmployeeSalary
    FROM   ORG_Region ogr
           INNER JOIN DailyAllowanceForm AS daf
                    ON daf.Region_ID = ogr.Region_ID
           INNER JOIN NightAllowance AS naf
                    ON naf.Region_ID = ogr.Region_ID
           INNER JOIN CashAdvance AS caf
                    ON caf.Region_ID = ogr.Region_ID
           INNER JOIN Attandence AS att
                    ON att.Region_ID = ogr.Region_ID
           INNER JOIN EmployeeExpensesForm AS eef
                    ON eef.Region_ID = ogr.Region_ID
           INNER JOIN MobileAllowance AS maf
                    ON maf.Region_ID = ogr.Region_ID
           INNER JOIN OnDutyForms AS odf
                    ON odf.Region_ID = ogr.Region_ID
           INNER JOIN Employee AS emp
                    ON emp.Region = ogr.Region_ID
       GROUP  BY ogr.Region_ID,ogr.Region_Name
    

    另一种方式是

    SELECT  ogr.Region_ID ,
        ogr.Region_Name ,
        ( SELECT    ISNULL(( SUM(daf.Total_Allowance) ), 0)
          FROM      DailyAllowanceForm AS daf
          WHERE     daf.Region_ID = ogr.Region_ID
        ) AS DailyAllowance ,
        ( SELECT    ISNULL(( SUM(naf.Total_Allowance) ), 0)
          FROM      NightAllowance AS naf
          WHERE     naf.Region_ID = ogr.Region_ID
        ) AS NightAllowance ,
        ( SELECT    ISNULL(( SUM(caf.Total_Amount) ), 0)
          FROM      CashAdvance AS caf
          WHERE     caf.Region_ID = ogr.Region_ID
        ) AS AdvanceCash ,
        ( SELECT    ISNULL(( SUM(att.Extra_Amounts) ), 0)
          FROM      Attandence AS att
          WHERE     att.Region_ID = ogr.Region_ID
        ) AS OverTime ,
        ( SELECT    ISNULL(( SUM(eef.Total_Amount) ), 0)
          FROM      EmployeeExpensesForm AS eef
          WHERE     eef.Region_ID = ogr.Region_ID
        ) AS EmployeeExpense ,
        ( SELECT    ISNULL(( SUM(maf.Total_Amount) ), 0)
          FROM      MobileAllowance AS maf
          WHERE     maf.Region_ID = ogr.Region_ID
        ) AS MobileAllowance ,
        ( SELECT    ISNULL(( SUM(odf.On_Week_Amount) ), 0)
          FROM      OnDutyForms AS odf
          WHERE     odf.Region_ID = ogr.Region_ID
        ) AS OnWeek ,
        ( SELECT    ISNULL(( SUM(emp.Salary) ), 0)
          FROM      Employee AS emp
          WHERE     emp.Region_ID = ogr.Region_ID
        ) AS EmployeeSalary
     FROM    ORG_Region ogr
     GROUP BY ogr.Region_ID ,
     ogr.Region_Name
    

    【讨论】:

      【解决方案3】:

      干净的解决方案是使用 CTE,烹饪聚合值然后加入它:

      ;WITH daf as (
         SELECT Region_ID, SUM(Total_Allowance) as DailyAllowance 
         FROM DailyAllowanceForm GROUP BY Region_ID
      ), naf as (
         SELECT Region_ID, SUM(Total_Allowance) as NightAllowance 
         FROM NightAllowance GROUP BY Region_ID
      ), caf as (
        ...
      ) 
      SELECT ogr.Region_ID, ogr.Region_Name, 
             coalesce(daf.DailyAllowance, 0) AS DailyAllowance,
             coalesce(naf.NightAllowance, 0) AS NightAllowance,
             ...
      FROM
         ORG_Region ogr 
      LEFT OUTER JOIN 
         daf               ON daf.Region_ID = ogr.Region_ID
      LEFT OUTER JOIN  
         naf               ON naf.Region_ID = ogr.Region_ID
         ...
      GROUP BY ogr.Region_ID,ogr.Region_Name
      

      【讨论】:

        【解决方案4】:

        试试这个:

        SELECT ogr.Region_ID, ogr.Region_Name, ISNULL(daf.DailyAllowance, 0) AS DailyAllowance, ISNULL(naf.NightAllowance, 0) AS NightAllowance, 
               ISNULL(caf.AdvanceCash, 0) AS AdvanceCash, ISNULL(att.OverTime, 0) AS OverTime, ISNULL(eef.EmployeeExpense, 0) AS EmployeeExpense, 
               ISNULL(maf.MobileAllowance, 0) AS MobileAllowance, ISNULL(odf.OnWeek, 0) AS OnWeek, ISNULL(emp.EmployeeSalary, 0) AS EmployeeSalary
        FROM   ORG_Region ogr
        LEFT OUTER JOIN (SELECT Region_ID, SUM(Total_Allowance) DailyAllowance FROM DailyAllowanceForm GROUP BY Region_ID) AS daf ON daf.Region_ID = ogr.Region_ID
        LEFT OUTER JOIN (SELECT Region_ID, SUM(Total_Allowance) NightAllowance FROM NightAllowance GROUP BY Region_ID) AS naf ON naf.Region_ID = ogr.Region_ID
        LEFT OUTER JOIN (SELECT Region_ID, SUM(Total_Amount) AS AdvanceCash FROM CashAdvance GROUP BY Region_ID) AS caf ON caf.Region_ID = ogr.Region_ID
        LEFT OUTER JOIN (SELECT Region_ID, SUM(Extra_Amounts) AS OverTime FROM Attandence GROUP BY Region_ID) AS att ON att.Region_ID = ogr.Region_ID
        LEFT OUTER JOIN (SELECT Region_ID, SUM(Total_Amount) AS EmployeeExpense FROM EmployeeExpensesForm GROUP BY Region_ID) AS eef ON eef.Region_ID = ogr.Region_ID
        LEFT OUTER JOIN (SELECT Region_ID, SUM(Total_Amount) AS MobileAllowance FROM MobileAllowance GROUP BY Region_ID) AS maf ON maf.Region_ID = ogr.Region_ID
        LEFT OUTER JOIN (SELECT Region_ID, SUM(On_Week_Amount) AS OnWeek FROM OnDutyForms GROUP BY Region_ID) AS odf ON odf.Region_ID = ogr.Region_ID
        LEFT OUTER JOIN (SELECT Region_ID, SUM(Salary) AS EmployeeSalary FROM Employee GROUP BY Region_ID) AS emp ON emp.Region = ogr.Region_ID;
        

        【讨论】:

          猜你喜欢
          • 2017-07-14
          • 2015-05-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-21
          • 2015-07-21
          相关资源
          最近更新 更多