【问题标题】:SQL Sum is counting more than onceSQL Sum 计数不止一次
【发布时间】:2011-11-22 10:27:29
【问题描述】:

我对此有困难。在我放入第一个内部联接之前,此查询在计算总和时运行良好。在表 tbl_companies 中,每个公司有多个条目,例如,该表可能如下所示:

priority      company     externalip
1             bla         9.9.9.9
1             bla         3.3.3.3
1             company2    3.56.6.6

在下面的查询中,总和(计算 As TotalWithoutNew 和 TotalAllId 当公司有多个条目时加倍,如果有三个条目则增加三倍等。我想要它做的只是从表 tbl_companies

SELECT b.company, 
       b.priority, 
       i.concom, 
       Coalesce (SUM(CASE 
                       WHEN c.category_id = '30' THEN 0 
                       ELSE t.logmins 
                     END), 0)       AS totalwithoutnew, 
       Coalesce (SUM(t.logmins), 0) AS totalallid 
FROM   helpdesk3.dbo.inquiry AS i 
       INNER JOIN [Check].[dbo].[tbl_companies] AS b 
         ON i.concom = b.company COLLATE sql_latin1_general_cp1_ci_as 
       INNER JOIN timelog AS t 
         ON t.inquiry_id = i.inquiry_id 
       INNER JOIN prod AS p 
         ON i.prod_id = p.prod_id 
       INNER JOIN category AS c 
         ON p.category_id = c.category_id 
WHERE  ( Datepart(yyyy, escdate) = 2011 ) 
GROUP  BY i.concom, 
          b.company, 
          b.priority 
ORDER  BY totalwithoutnew DESC, 
          b.priority DESC    

【问题讨论】:

  • priority、company 和 externalip(一起)是否唯一标识 tbl_companies 记录?

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


【解决方案1】:

您应该拆分查询以避免来自 tbl_companies 的多个结果。

select distinct b.company, 
       b.priority, 
       x.concom, 
       x.totalwithoutnew, 
       x.totalallid 
FROM    (
            SELECT i.concom, 
                   Coalesce (SUM(CASE 
                                   WHEN c.category_id = '30' THEN 0 
                                   ELSE t.logmins 
                                 END), 0)       AS totalwithoutnew, 
                   Coalesce (SUM(t.logmins), 0) AS totalallid 
            FROM   helpdesk3.dbo.inquiry AS i 
                   INNER JOIN timelog AS t 
                     ON t.inquiry_id = i.inquiry_id 
                   INNER JOIN prod AS p 
                     ON i.prod_id = p.prod_id 
                   INNER JOIN category AS c 
                     ON p.category_id = c.category_id 
            WHERE  ( Datepart(yyyy, escdate) = 2011 ) 
            GROUP  BY i.concom 
            ) x
INNER JOIN [Check].[dbo].[tbl_companies] AS b 
          ON x.concom = b.company COLLATE sql_latin1_general_cp1_ci_as 

ORDER  BY x.totalwithoutnew DESC, 
          b.priority DESC  

【讨论】:

  • 太棒了!这工作正常,有一个错误的逗号,我在初始阶段添加了一个不同的,但这是我需要的。谢谢约翰!
  • 哦,我明白了。我只是在修改您的原始查询,所以我一定错过了逗号。
【解决方案2】:

您从INQUIRY 表到tbl_companies 表的连接将生成一组三行(当有三个公司时),因此到TIMELOG 表的下一个连接也将具有三个值对于每个 TIMELOG.LOGMINS 列 - 因此COALESCE (SUM(CASE WHEN C.CATEGORY_ID = '30' THEN 0 ELSE t.LOGMINS END), 0) AS TotalWithoutNew 计算将增加三倍。

select 
...
FROM helpdesk3.dbo.INQUIRY AS i 
inner join [Check].[dbo].[tbl_companies] As B ON i.CONCOM = B.company COLLATE SQL_Latin1_General_CP1_CI_AS 
INNER JOIN TIMELOG AS t ON t.INQUIRY_ID = i.INQUIRY_ID 
...

如果您希望单个公司出现在 select 中而不是将总和相乘,请从 where 子句和 group by 子句中删除与 tbl_companies 的连接。沿着这些思路应该可以工作(尽管我无法确定数据的确切结构):

select 
(select company from [tbl_companies] where company = i.concom) as company,
(select priority from [tbl_companies] where company = i.concom) as priority,
...
FROM helpdesk3.dbo.INQUIRY AS i 
INNER JOIN TIMELOG AS t ON t.INQUIRY_ID = i.INQUIRY_ID 
...

【讨论】:

  • 有没有办法解决这个问题?
  • 我已经提出了一种解决方法,如果每次查询的公司和优先级列都相同,这将起作用 - 如果它们不同,那么我建议使用临时表来保存查询/公司信息。
【解决方案3】:

有几种方法可以做到这一点。假设 priority、company 和 externalip 唯一标识 tbl_companies 记录,我建议:

SELECT b.company, 
       b.priority, 
       i.concom, 
       Coalesce (SUM(CASE 
                       WHEN c.category_id = '30' THEN 0 
                       ELSE t.logmins 
                     END), 0) / COUNT(DISTINCT b.externalip)  AS totalwithoutnew, 
       Coalesce (SUM(t.logmins), 0) / COUNT(DISTINCT b.externalip) AS totalallid 
FROM   helpdesk3.dbo.inquiry AS i 
       INNER JOIN [Check].[dbo].[tbl_companies] AS b 
         ON i.concom = b.company COLLATE sql_latin1_general_cp1_ci_as 
       INNER JOIN timelog AS t 
         ON t.inquiry_id = i.inquiry_id 
       INNER JOIN prod AS p 
         ON i.prod_id = p.prod_id 
       INNER JOIN category AS c 
         ON p.category_id = c.category_id 
WHERE  ( Datepart(yyyy, escdate) = 2011 ) 
GROUP  BY i.concom, 
          b.company, 
          b.priority 
ORDER  BY totalwithoutnew DESC, 
          b.priority DESC   

【讨论】:

    猜你喜欢
    • 2017-11-08
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多