我正在寻找一种使用存储在数据库中的比较运算符来构建脚本来比较两个不同表中数据的方法。
我通过两种方式解决:
但是我想解决不使用动态SQL或case语句的问题。
这是我的基本数据表:
create table #BaseData
(
ID int identity (1,1),
numR int,
ALertCode varchar (10),
numOp int,
BaseOrder int,
Criteri varchar (50),
Operator varchar (5),
BaseValue int
)
insert into #BaseData (numR, AlertCode, numOp, BaseOrder, Criteri, Operator, BaseValue)
select
ROW_NUMBER() over (order by (select null)) numR, ALertCode,
ROW_NUMBER() over (partition by ALertCode order by AlertCode )numOp,
DatosBase.BaseOrder, Criteri, Operator, DatosBase.ComparisonValue BaseValue
from
( select 'A_1_<1000 ' ALertCode , 1 BaseOrder, 'ES_CV_Basal 'Criteri, '=' Operator, 1 ComparisonValue
union all select 'A_1_<1000 ' ALertCode , 2 BaseOrder, 'Carga_Viral_Basal ' , '=' , 19
union all select 'A_1_<1000 ' ALertCode , 3 BaseOrder, 'Dias_CargaViralActual ' , NULL , NULL
union all select 'A_1_<1000 ' ALertCode , 4 BaseOrder, 'Carga_Viral_VIH_Previa_01 ' , NULL , NULL
union all select 'A_1_<1000 ' ALertCode , 5 BaseOrder, 'ES_CV_Basal_01 ' , NULL , NULL
union all select 'A_1_<1000 ' ALertCode , 6 BaseOrder, 'Carga_Viral_VIH_Previa_02 ' , NULL , NULL
union all select 'A_1_<1000 ' ALertCode , 7 BaseOrder, 'DiasCVPrevia_02 ' , NULL , NULL
union all select 'A_1_<1000 ' ALertCode , 8 BaseOrder, 'Dif_CVe_CVp' , NULL , NULL
union all
select 'A_2_<1000' ALertCode , 1 BaseOrder, 'ES_CV_Basal ' , '=' , 1
union all select 'A_2_<1000' ALertCode , 2 BaseOrder, 'Carga_Viral_VIH ' , '>' , 1000
union all select 'A_2_<1000' ALertCode , 3 BaseOrder, 'Dias_CargaViralActual ' , NULL , NULL
union all select 'A_2_<1000' ALertCode , 4 BaseOrder, 'Carga_Viral_VIH_Previa_01 ' , NULL , NULL
union all select 'A_2_<1000' ALertCode , 5 BaseOrder, 'TDias_01 ' , NULL , NULL
union all select 'A_2_<1000' ALertCode , 6 BaseOrder, 'Carga_Viral_VIH_Previa_02 ' , NULL , NULL
union all select 'A_2_<1000' ALertCode , 7 BaseOrder, 'TDias_02 ' , NULL , NULL
union all select 'A_2_<1000' ALertCode , 8 BaseOrder, 'Dif_CVe_CVp' , NULL , NULL
union all
select 'A_1000' ALertCode , 1 BaseOrder, 'ES_CV_Basal ' , NULL , NULL
union all select 'A_1000' ALertCode , 2 BaseOrder, 'Carga_Viral_VIH ' , '>=' , 1000
union all select 'A_1000' ALertCode , 3 BaseOrder, 'Dias_CargaViralActual ' , '>=' , 168
union all select 'A_1000' ALertCode , 4 BaseOrder, 'Carga_Viral_VIH_Previa_01 ' , '=' , 19
union all select 'A_1000' ALertCode , 5 BaseOrder, 'TDias_01 ' , '>=' , 168
union all select 'A_1000' ALertCode , 6 BaseOrder, 'Carga_Viral_VIH_Previa_02 ' , NULL , NULL
union all select 'A_1000' ALertCode , 7 BaseOrder, 'TDias_02 ' , NULL , NULL
union all select 'A_1000' ALertCode , 8 BaseOrder, 'Dif_CVe_CVp' , NULL , NULL
)BaseData
order by ALertCode, BaseOrder
这是我的比较数据表:
create table #ComparisonData
(
ID int identity (1,1),
ComparisonOrder int,
EvaluationCriteri varchar(50),
ComparisonValue decimal (10,6)
)
insert into #ComparisonData (ComparisonOrder, EvaluationCriteri, ComparisonValue)
select ComparisonOrder, EvaluationCriteri, ComparisonValue
from
( select 1 ComparisonOrder, 'ES_CV_Basal' EvaluationCriteri, 2 ComparisonValue
union all select 2 , 'Carga_Viral_VIH' EvaluationCriteri, 1001 ComparisonValue
union all select 3 , 'TDias' EvaluationCriteri, 169 ComparisonValue
union all select 4 , 'Carga_Viral_VIH' EvaluationCriteri, 19 ComparisonValue
union all select 5 , 'TDias' EvaluationCriteri, 169 ComparisonValue
union all select 6 , 'Carga_Viral_VIH' EvaluationCriteri, 387 ComparisonValue
union all select 7 , 'TDias' EvaluationCriteri, 265 ComparisonValue
union all select 8 , 'Dif_CVe_CVp' EvaluationCriteri, -0.33 ComparisonValue
)ComparisonData
这是我用来比较数据的表:
create table #AlertDetected
(
ID int identity (1,1),
numR int,
AlertCode varchar (10),
numOp int,
BaseOrder int,
Criteri varchar(50),
Operator varchar(5),
BaseValue int,
ComparisonOrder int,
EvaluationCriteri varchar (50),
ComparisonValue decimal(10,6)
)
insert into #AlertDetected (numR, AlertCode, numOp, BaseOrder, Criteri, Operator, BaseValue, ComparisonOrder, EvaluationCriteri, ComparisonValue)
select ROW_NUMBER() over (order by (select null)) numR, ALertCode,
ROW_NUMBER() over (partition by ALertCode order by AlertCode )numOp,
BaseOrder, Criteri, Operator, BaseValue, dc.ComparisonOrder,EvaluationCriteri, ComparisonValue
from #BaseData db
left join #ComparisonData dc
on db.BaseOrder = dc.ComparisonOrder
where db.BaseValue is not null
这是我的动态SQL解决方案:
select 'select max(AlertResult)AlertResult from ( ' + stuff(( select 'union all' + Operacion
from
( select stuff(( select + concat ( ' ' , Operacion)
from
(
select numR, AlertCode, BaseOrder, concat (iif (numOp = 1 , ' select iif( ', ' and ' ), ComparisonValue , Operator , ' ', BaseValue)Operacion
from
( select numR, AlertCode, BaseOrder, numOp , BaseValue , Operator , case when numOp<> 8 then floor( ComparisonValue ) else cast ( ComparisonValue as float ) end ComparisonValue --
from #AlertDetected
)t
)x
where x.AlertCode = isc.AlertCode FOR XML PATH(''), TYPE ).value('.[1]', 'varchar(max)'), 1, 1, '') + ' , '+''''+AlertCode+''''+ ', '+ ''''+'0'+ '''' + ' ) AlertResult ' as Operacion
from #AlertDetected isc group by AlertCode
)X
FOR XML PATH(''), TYPE ).value('.[1]', 'varchar(max)'), 1, 9, '') + ' ) Datos'as CamposInforme
这是我的案例陈述解决方案:
select iif (sum(Result) = row_count , AlertCode, ' ')AlertDetected
from
( select numR, AlertCode, numOp, BaseOrder, Criteri, ComparisonValue, Operator, BaseValue,
case when Operator ='=' then iif (ComparisonValue = BaseValue, 1,0)
when Operator ='<' then iif (ComparisonValue < BaseValue, 1,0)
when Operator ='>' then iif (ComparisonValue > BaseValue, 1,0)
when Operator ='>=' then iif (ComparisonValue >= BaseValue, 1,0)
when Operator ='<=' then iif (ComparisonValue <= BaseValue, 1,0) end Result , row_count
from
( select numR, a.AlertCode, Criteri, BaseOrder, numOp , BaseValue , Operator ,
case when numOp<> 8 then floor( ComparisonValue ) else cast ( ComparisonValue as float ) end ComparisonValue , c.row_count
from #AlertDetected a
inner join
( select AlertCode, COUNT(*) AS row_count
FROM dbo.#AlertDetected
group by AlertCode
)c on a.AlertCode = c.AlertCode
)d
)d group by AlertCode, row_count
我需要基于比较运算符比较CompareValue和BaseValue列之间的数据,并且我必须获取完全符合CompareValue和BaseValue之间的每个比较的警报代码。
有一些方法可以实现,而无需使用动态SQL或case语句?
答案 0 :(得分:0)
您在需要使用锤子的地方使用了锯。 SQL旨在非常有效地持久化数据。它不是为此设计的。 您应该学习C#或Java。用适当的语言可以很容易地做到这一点。
但是,如果必须使用SQL,则应该为每个比较创建一个proc。 proc应该接受您正在比较的两个值的输入。这样,进行一次比较的所有逻辑都包含在自己的小胶囊中。
通过选择要与比较运算符一起放在表中的proc名称,动态调用所需的proc。
如果您想执行“>”,那么当您传递要比较的值时,将调用“ GreaterThan”过程。
如果要提高效率,请为要比较的事物创建表类型,然后一次传递整个项目列表。