如何针对包含数字和文本的varchar列运行条件聚合

时间:2013-03-05 15:40:57

标签: sql sql-server-2008

我是SQL Server 2008的新手,我遇到了一个问题。我有一个包含varchar(255)列的表,其中包含实验结果。该列中的数据如下所示:

result_value
7.0
162
NEGATIVE
SEE NOTE
9.6

现在,我要做的是运行以下查询:

;WITH PatientData (patient_id,last_name, first_name, ethnic_group,
race, icdcode, encounter_date, test_performed, result_value,
result_units )
AS
(
SELECT pat.patient_id, pat.last_name, Pat.first_name, pat.ethnic_group,
pat.race, pl.icdcode, enc.encounter_date, lab.test_performed, lab.result_value,
lab.result_units
FROM dbo.dem_patient pat
RIGHT JOIN dbo.med_problemlist as pl
ON pat.patient_id = pl.patient_id
JOIN dbo.enc_encounter as enc
ON pat.patient_id = enc.patient_id
JOIN dbo.med_labresult as lab
ON pat.patient_id = lab.patient_id
WHERE pl.icdcode like '250%' AND
enc.encounter_date >= '01/01/2012' AND enc.encounter_date <= '12/31/2012' AND
pat.last_name != 'test' AND (lab.test_performed = 'HgbA1c' OR 
lab.test_performed = 'Hemoglobin A1c')
GROUP BY pat.patient_id, pat.last_name, Pat.first_name, pat.ethnic_group,
pat.race, pl.icdcode, enc.encounter_date, lab.test_performed, lab.result_value,
lab.result_units
)
select sum(case when result_value < 7.0 then 1 else 0 end) as [LessThan7%],
       sum(case when result_value >= 7.0 and result_value < 8.0 then 1 else 0 end) as [7%to8%],
       sum(case when result_value >= 8.0 and result_value < 9.0 then 1 else 0 end) as [8%to9%],
       sum(case when result_value >= 9.0 then 1 else 0 end) as [GreaterThan9%]
FROM PatientData pd1 
WHERE EXISTS (SELECT patient_id 
                FROM PatientData pd2 
                WHERE pd2.patient_id  = pd1.patient_id  
                GROUP BY patient_id 
                HAVING COUNT(*)>1 )

因为我只应该返回已经进行过A1c测试的患者,所以results_value列应该总是看起来像xx - 但是,我尝试运行此查询,我得到“Arithmic overflow error将varchar转换为数据类型numeric。

虽然我意识到将这些不同类型的数据放在同一列中并不理想,但我没有创建数据库 - 我只需要使用它。反正有这个问题吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您可以使用此类解决方案。让我们考虑一下这个表和数据。

CREATE TABLE [tb](
[id] [int] IDENTITY(1,1) NOT NULL primary key,
[result] [varchar](50) NULL,
) ON [PRIMARY] 
INSERT [tb] ([id], [result]) VALUES (1, N'12')
INSERT [tb] ([id], [result]) VALUES (2, N'24')
INSERT [tb] ([id], [result]) VALUES (3, N'35')
INSERT [tb] ([id], [result]) VALUES (4, N'NEGATIVE')
INSERT [tb] ([id], [result]) VALUES (5, N'SEE NOTE')
INSERT [tb] ([id], [result]) VALUES (6, N'15.5')
INSERT [tb] ([id], [result]) VALUES (7, N'16.4')

您可以使用ASCII功能(ASCII返回字符表达式最左侧字符的ASCII代码值。)从此示例数据中获取正确的数字

 select id,ascii(result),convert(decimal(16,2),result) as result from tb
 where ascii(result)>=ascii('0') and ascii(result)<=ascii('9')
  union 
 select id,ascii(result),-1.0 as result from tb
 where ascii(result)<=ascii('0') or ascii(result)>=ascii('9')

您可以根据需要标记无效记录。您可以为此查询添加更多逻辑。您可以将其用作子查询或“加入”。  我希望它会对你有所帮助。

Marcin Pazgier