TSQL加入具有多个计数的表

时间:2014-09-02 14:16:19

标签: sql sql-server tsql stored-procedures

我有一张表,我试图从使用2个左连接的相同数据中获得2个不同的计数。

无论出于何种原因,它都会复制数据并提供不正确的结果,我不确定原因。

这是我到目前为止的查询,我认为它将起作用:

DECLARE @locale INT = '14'

SELECT TOP 50
    E.[DepartmentDesc] AS department,
    COUNT(N.[nomineeQID]) AS totalNominations,
    COUNT(S.[subQID]) AS totalSubmissions,
    COUNT(N.[nomineeQID]) + COUNT(S.[subQID]) AS total
FROM 
    employees AS E
LEFT JOIN 
    submissions AS S ON E.[qid] = S.[subQID] AND S.[statusID] = 3
                        AND S.[locationID] = @locale
LEFT JOIN 
    submissions AS N ON E.[qid] = N.[nomineeQID] AND N.[statusID] = 3
                     AND N.[locationID] = @locale
GROUP BY
    E.[DepartmentDesc]
ORDER BY
    totalNominations DESC

以下是数据的SQL小提琴:http://sqlfiddle.com/#!3/4e6b5/1

结果应该如下,但它提供了偏斜的数字:

  • 总提名应为3
  • 提交的总数应为2
  • 总计应为5

我感觉很接近,但数学不合作!

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您正在为每个部门获取笛卡尔积。对查询的最简单修复是使用count(distinct)

                    COUNT(DISTINCT N.[nomineeQID]) AS totalNominations,
                    COUNT(DISTINCT S.[subQID])     AS totalSubmissions,
                    COUNT(DISTINCT N.[nomineeQID]) + COUNT(DISTINCT S.[subQID]) AS total

更正确的解决方法是在执行join之前在子查询中执行聚合。

编辑:

由于重复问题,请改用SubmissionId

                    COUNT(DISTINCT N.SubmissionId) AS totalNominations,
                    COUNT(DISTINCT S.SubmissionId)     AS totalSubmissions,
                    COUNT(DISTINCT N.SubmissionId) + COUNT(DISTINCT S.SubmissionId) AS total

答案 1 :(得分:0)

试试这个:

DECLARE @locale INT = '14'

select TOP 50 t.department, sum(t.totalSubmissions),
sum(t.totalNominations), sum(t.total)
from 
(SELECT
    E.[DepartmentDesc]    AS department,

    (select COUNT(S.[subQID])
    from submissions AS S
    where E.[qid] = S.[subQID]
    AND S.[statusID] = 3
    AND S.[locationID] = @locale) AS totalSubmissions,

    (select COUNT(N.[nomineeQID])
    from submissions AS N
    where E.[qid] = N.[nomineeQID]
    AND N.[statusID] = 3
    AND N.[locationID] = @locale) AS totalNominations,

    (select COUNT(S.[subQID])
    from submissions AS S
    where E.[qid] = S.[subQID]
    AND S.[statusID] = 3
    AND S.[locationID] = @locale) +
    (select COUNT(N.[nomineeQID])
    from submissions AS N
    where E.[qid] = N.[nomineeQID]
    AND N.[statusID] = 3
    AND N.[locationID] = @locale) AS total  

FROM employees AS E
where exists(
  select 'submission'
  from submissions AS S
  where E.[qid] = S.[subQID]
  AND S.[statusID] = 3
  AND S.[locationID] = @locale
) or
exists(
 select 'nomination'
 from submissions AS N
 where E.[qid] = N.[nomineeQID]
 AND N.[statusID] = 3
 AND N.[locationID] = @locale
 )
) as t
group by t.department
ORDER BY sum(t.totalNominations) DESC

转到SqlFiddle