Я ищу способ создания сценария для сравнения данных из двух разных таблиц, используя операторы сравнения, хранящиеся в базе данных.
Мне удалось решить двумя способами:
- с использованием динамического SQL
- с использованием операторов case
, но я хотел бы решить, используя что-то, что не включает динамический 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
Мне нужно сравнить данные между столбцами ComparisonValue и BaseValue на основе операторов сравнения, и ядолжен получить код предупреждения, который точно соответствует каждому из сравнений между ComparisonValue и BaseValue.
Будет ли какой-то способ добиться этого без использования динамического SQL или оператора case?