1

我正在 SQL Server Management Studio 2005 中编写一个存储过程,以返回两个不同时间段(本月至今和年初至今)的状态和策略计数列表。我创建了几个视图来收集所需的数据和一个存储过程,以便在 Reporting Services 报表中使用。

下面是我的存储过程:

SELECT DISTINCT
    S.[State],
    COUNT(HP_MTD.PolicyID) AS PolicyCount_MTD,
    COUNT(HP_YTD.PolicyID) AS PolicyCount_YTD
FROM tblStates S
    LEFT OUTER JOIN vwHospitalPolicies HP_MTD ON S.[State] = HP.[State]
        AND HP.CreatedDate BETWEEN DATEADD(MONTH, -1, GETDATE()) AND GETDATE()
    LEFT OUTER JOIN vwHospitalPolicies HP_YTD ON S.[State] = HP.[State]
        AND HP.CreatedDate BETWEEN DATEADD(YEAR, -1, GETDATE()) AND GETDATE()
GROUP BY S.[State]
ORDER BY S.[State] ASC

我遇到的问题是,当添加第二个 LEFT OUTER JOIN 时,我的计数会膨胀,即使是没有引用第二个连接的 COUNT() 也是如此。我需要左加入,因为并非所有州都会在给定时期内制定政策,但它们仍应出现在报告中。

任何建议将不胜感激!

4

2 回答 2

2

听起来你需要:

COUNT(DISTINCT HP_MTD.PolicyID) AS PolicyCount_MTD,
COUNT(DISTINCT HP_YTD.PolicyID) AS PolicyCount_YTD

代替:

COUNT(HP_MTD.PolicyID) AS PolicyCount_MTD,
COUNT(HP_YTD.PolicyID) AS PolicyCount_YTD

您的原始查询包括第二个联接中的匹配行数。在内部添加一个DISTINCT子句将其COUNT限制为 PolicyID 的唯一出现。

于 2012-04-13T15:33:58.180 回答
0

对于这类工作,我更喜欢 CTE——它们基本上是一种内联视图。

您的实际问题是,某些策略在两个计数列中都被计算了两次——一次是本月至今,一次是年初至今。所以,如果你有这样的源表:

year-to-date
state   policy
==================
1       1
1       2
1       3
2       4

month-to-date
state   policy
==================
1       1
1       2

s的结果表JOIN(在评估之前COUNT)如下所示:

temp
state  monthPolicy  yearPolicy
================================
1      1            1
1      1            2
1      1            3
1      2            1
1      2            2
1      2            3
2      -            4

显然不是你想要的。通常,解决方案是使用 CTE 或其他表引用来呈现最终连接的汇总记录。像这样的东西:

WITH PoliciesMonthToDate (state, count) as (
                          SELECT state, COUNT(*)
                          FROM vwHospitalPolicies
                          WHERE createdDate >= DATEADD(MONTH, -1, GETDATE())
                          AND createdDate < DATEADD(DAY, 1, GETDATE())
                          GROUP BY state),
     PoliciesYearToDate (state, count) as (
                         SELECT state, COUNT(*)
                         FROM vwHospitalPolicies
                         WHERE createdDate >= DATEADD(YEAR, -1, GETDATE())
                         AND createdDate < DATEADD(DAY, 1, GETDATE())
                         GROUP BY state)
SELECT a.state, COALESCE(b.count, 0) as policy_count_mtd, 
                COALESCE(c.count, 0) as policy_count_ytd
FROM tblStates a
LEFT JOIN PoliciesMonthToDate b
ON b.state = a.state
LEFT JOIN PoliciesYearToDate c
ON c.state = a.state
ORDER BY a.state

(轻微的挑剔 - 不要为表和视图使用前缀。这是噪音,如果由于某种原因在它们之间切换,则需要更改代码。否则,名称会误导)

于 2012-04-13T16:02:36.540 回答