SQL AVG() 函数对于三列返回错误结果

3

我正在编写一个查询,应该给我返回一个 count() 和三个 avg()。这个 count() 可以正常工作,但是这些 avg() 函数返回的结果错误。我正在处理的数据看起来像这样:

MD Name |    PT | Med Staff | LOS | DRG Bench | LOS - Bench
MCP     | 12345 | Ortho SX  |  5  |    4      |       1
MCP     | 25879 | Ortho SX  |  3  |    5      |      -2
MCP     | 98556 | Ortho SX  |  4  |    5      |      -1
... 

我希望的输出是:

MD Name | # PT | Med Staff | Avg LOS | Avg DRG Bench | AVG LOS - Bench
MCP     |   3  | Ortho SX  |    4    |       4.66    |       0

我得到的平均值结果是错误的。 我有一个特别的案例,其中包含以下内容:

MD Name | LOS    | Bench  | LOS - Bench
MCP     | 2.0000 | 1.8000 |    0.2000
MCP     | 1.0000 | 1.7000 |   -0.7000
MCP     | 25.0000| 4.9000 |   20.1000
MCP     | 4.0000 | 2.2000 |    1.8000

对于平均停留时间和平均工作台,我得到的结果分别是9.000000和2.780000,与实际值8.000000和2.65相比存在显著差异;而对于停留时间和工作台之间的关系,我得到的结果是6.220000,而实际值为5.35。这些差异非常明显,必须精确到小数点后两位。

以下是我使用的SQL,使用的是SQL Server 2008

DECLARE @STARTDATE DATETIME
DECLARE @ENDATE DATETIME

SET @STARTDATE = '2013-05-01'
SET @ENDATE = '2013-05-31'

SELECT DISTINCT pv.pract_rpt_name AS 'PHYSICIAN'
, COUNT(DISTINCT vr.pt_id) AS '# PTS' 
--, pv.spclty_desc AS 'SPECIALTY'
, pv.med_staff_dept AS 'MED STAFF'
, AVG(vr.len_of_stay) AS 'LOS'
, AVG(vr.drg_std_days_stay) AS 'DRG LOS BENCH'
, AVG(vr.len_of_stay - vr.drg_std_days_stay) AS 'LOS - DRG BENCH'

FROM smsmir.vst_rpt vr
LEFT OUTER JOIN smsmir.pyr_plan pp <-- removed and fixed
ON vr.pt_id = pp.pt_id <-- removed and fixed
JOIN smsdss.pract_dim_v pv
ON vr.adm_pract_no = pv.src_pract_no

WHERE vr.adm_dtime BETWEEN @STARTDATE AND @ENDATE
AND vr.vst_type_cd = 'I'
AND pv.spclty_desc != 'NO DESCRIPTION'
--AND pv.spclty_desc NOT LIKE 'HOSPITALIST%'
AND vr.drg_std_days_stay IS NOT NULL
AND pv.pract_rpt_name != '?'
AND pv.orgz_cd = 's0x0'
AND pv.med_staff_dept IN (
'INTERNAL MEDICINE',
'FAMILY PRACTICE',
'SURGERY'
)
GROUP BY pv.pract_rpt_name, pv.med_staff_dept
ORDER BY pv.med_staff_dept, AVG(vr.len_of_stay - vr.drg_std_days_stay)DESC

感谢您的时间和努力。

源列的数据类型是什么? - Rikalous
2
您在查询中使用了一个似乎没有被使用的表的 OUTER JOIN。尝试删除该子句并查看问题是否仍然存在。 - Rikalous
2
我想说,查询结果可能比你想象的要多。由于使用了“DISTINCT”,所以“Count”可能是正确的。 - Nikola Markovinović
@Rikalous,是那个OUTER JOIN的问题,现在我已经想不起来为什么要加它了...现在我得思考一下为什么在我的原始查询中要加它,但还是谢谢你,这样就解决了,把它作为一个解决方案发布,这样我就可以接受了。 - MCP_infiltrator
2个回答

1
唯一的可能性是您表中选择的行中存在NULL值... 如果有空列,AVG将忽略它,而不是计数...
DECLARE @STARTDATE DATETIME
DECLARE @ENDATE DATETIME

SET @STARTDATE = '2013-05-01'
SET @ENDATE = '2013-05-31'

SELECT DISTINCT pv.pract_rpt_name AS 'PHYSICIAN'
, COUNT(DISTINCT vr.pt_id) AS '# PTS' 
--, pv.spclty_desc AS 'SPECIALTY'
, pv.med_staff_dept AS 'MED STAFF'
, AVG(ISNULL(vr.len_of_stay,0)) AS 'LOS'
, AVG(ISNULL(vr.drg_std_days_stay,0)) AS 'DRG LOS BENCH'
, AVG(ISNULL((vr.len_of_stay - vr.drg_std_days_stay),0)) AS 'LOS - DRG BENCH'

FROM smsmir.vst_rpt vr
LEFT OUTER JOIN smsmir.pyr_plan pp
ON vr.pt_id = pp.pt_id
JOIN smsdss.pract_dim_v pv
ON vr.adm_pract_no = pv.src_pract_no

WHERE vr.adm_dtime BETWEEN @STARTDATE AND @ENDATE
AND vr.vst_type_cd = 'I'
AND pv.spclty_desc != 'NO DESCRIPTION'
--AND pv.spclty_desc NOT LIKE 'HOSPITALIST%'
AND vr.drg_std_days_stay IS NOT NULL
AND pv.pract_rpt_name != '?'
AND pv.orgz_cd = 's0x0'
AND pv.med_staff_dept IN (
'INTERNAL MEDICINE',
'FAMILY PRACTICE',
'SURGERY'
)
GROUP BY pv.pract_rpt_name, pv.med_staff_dept
ORDER BY pv.med_staff_dept, AVG(vr.len_of_stay - vr.drg_std_days_stay)DESC

1
您查询中的外连接可能会影响AVG函数操作的行数。如果您不需要它(我无法看到查询中其他地方引用该表),请尝试将其删除。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接