在SQL请求上使用JOIN时出现错误的SUM

时间:2013-09-16 10:34:07

标签: sql sql-server sql-server-2008-r2

您好我有两张包含大量数据的表格。我必须得到两个表的一些数据。要做到这一点,我使用inner join。但是当我使用SUM时,我得到了错误的结果。我知道结果会随着返回的行数而成倍增加。我怎么能得到这个呢?

请求:

select  SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_PrimeNette ELSE 0 END) AS 'cot nette',
    SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_PrimeNette ELSE 0 END) AS 'Fond comp',
    SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_PrimeNette ELSE 0 END) AS 'Carte Verte',
    SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_PrimeNette ELSE 0 END) AS 'Adhesion',
    SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe',
    SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe Fond Comp',
    SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe Adhésion',
    SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe carte verte',
    SUM(hst.Q_Access) as 'Access'
from  OtoHistorique hst
inner Join OtoHistoriqueDet det On det.IdHistorique = hst.IdHistorique
where hst.POLICE = 3221086

当预期结果为20

时,我在访问列中获得60

任何人都可以帮我这个吗?很抱歉,如果我在请求中使用了错误的语法,但我只是SQL的初学者,目前结果比语法更重要。

2 个答案:

答案 0 :(得分:1)

表之间可能存在一对多的关系,这意味着SUM的某些值会重复。 您可以通过避免这样的连接来解决这个问题:

select  SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_PrimeNette ELSE 0 END) AS 'cot nette',
    SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_PrimeNette ELSE 0 END) AS 'Fond comp',
    SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_PrimeNette ELSE 0 END) AS 'Carte Verte',
    SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_PrimeNette ELSE 0 END) AS 'Adhesion',
    SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe',
    SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe Fond Comp',
    SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe Adhésion',
    SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe carte verte',
    (SELECT SUM(hst.Q_Access) 
     FROM OtoHistorique hst 
     WHERE det.IdHistorique = hst.IdHistorique) as 'Access' 
FROM OtoHistoriqueDet det 
WHERE EXISTS (SELECT 1 
              FROM OtoHistorique hst2 
              WHERE hst2.POLICE = 3221086 
                AND hst2.IdHistorique = det.IdHistorique)

这可能会更加优化,但我们需要更多关于两个表之间逻辑的信息。

答案 1 :(得分:0)

一种方法是在加入之前进行聚合:

select det.*,
       SUM(hst.Q_Access) as "Access"
from  OtoHistorique hst inner Join
      (select det.IdHistoric,
              SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_PrimeNette ELSE 0 END) as "cot nette"
              SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_PrimeNette ELSE 0 END) AS "Fond comp",
              SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_PrimeNette ELSE 0 END) AS "Carte Verte",
              SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_PrimeNette ELSE 0 END) AS "Adhesion",
              SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_Taxe ELSE 0 END) AS "Taxe",
              SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_Taxe ELSE 0 END) AS "Taxe Fond Comp",
              SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_Taxe ELSE 0 END) AS "Taxe Adhésion",
              SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_Taxe ELSE 0 END) AS "Taxe carte verte",
              SUM(hst.Q_Access) as "Access"
       from OtoHistoriqueDet det
       group by det.IdHistorique
      ) det
      On det.IdHistorique = hst.IdHistorique
where hst.POLICE = 3221086;

因为您正在过滤查询,所以这可能很昂贵。必须聚合整个详细信息表。因此,您可以在子查询中进行连接以进行过滤,然后再次进行计算:

select det.*,
       SUM(hst.Q_Access) as "Access"
from  OtoHistorique hst inner Join
      (select det.IdHistoric,
              SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_PrimeNette ELSE 0 END) as "cot nette"
              SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_PrimeNette ELSE 0 END) AS "Fond comp",
              SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_PrimeNette ELSE 0 END) AS "Carte Verte",
              SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_PrimeNette ELSE 0 END) AS "Adhesion",
              SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_Taxe ELSE 0 END) AS "Taxe",
              SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_Taxe ELSE 0 END) AS "Taxe Fond Comp",
              SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_Taxe ELSE 0 END) AS "Taxe Adhésion",
              SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_Taxe ELSE 0 END) AS "Taxe carte verte"
       from OtoHistoriqueDet det join
            OtoHistorique hst 
            On det.IdHistorique = hst.IdHistorique and hst.POLICE = 3221086
       group by det.IdHistorique
      ) det
      On det.IdHistorique = hst.IdHistorique
where hst.POLICE = 3221086;