Я ищу лучший подход к написанию высоко повторяющихся операторов sql. Я знаю, что могу это сделать, например, используя PHP-методы, но я бы хотел получить чистое SQL-решение. Я использую Sybase.Лучшая практика повторения SQL-заявлений
select
"SvHKeyId"=sh.KeyId,
"Scale"="Partial PTSD",
"ScoreText"=convert(varchar(3),
(case
when
(case
when
1 in (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum between 1 and 13)
and 1 in (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum between 15 and 21)
and 1 in (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum between 22 and 26)
then 'Yes'
else 'No'
end)
= 'Yes'
and
(case
when
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=30) >= 2
or (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=32) >= 2
or (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=33) >= 2
or (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=29) >= 2
or (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=45) >= 2
then 1
else 0
end)
+
(case
when
(case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=36) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=44) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=42) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=34) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=35) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46) >= 2 then 1 else 0 end)
>= 3 then 1
else 0
end)
+
(case
when
(case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=40) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=43) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=28) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=39) >= 2 then 1 else 0 end)
>= 2 then 1
else 0
end)
>=2
then 'Yes'
else 'No'
end)
= 'Yes'
then 'Yes'
else 'No'
end)
),
"ScoreNum"=
(case
when
(case
when
1 in (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum between 1 and 13)
and 1 in (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum between 15 and 21)
and 1 in (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum between 22 and 26)
then 'Yes'
else 'No'
end)
= 'Yes'
and
(case
when
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=30) >= 2
or (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=32) >= 2
or (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=33) >= 2
or (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=29) >= 2
or (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=45) >= 2
then 1
else 0
end)
+
(case
when
(case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=36) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=44) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=42) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=34) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=35) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46) >= 2 then 1 else 0 end)
>= 3 then 1
else 0
end)
+
(case
when
(case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=40) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=43) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=28) >= 2 then 1 else 0 end)
+ (case when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=39) >= 2 then 1 else 0 end)
>= 2 then 1
else 0
end)
>=2
then 'Yes'
else 'No'
end)
= 'Yes'
then 1
else 0
end)
from
SurvHeader sh
where
sh.KeyId=105101
Это процедура подсчета очков. Я сравниваю серию суб-оценок, чтобы получить общий балл. Есть ли лучший подход к SQL? Полагаю, я могу использовать хранимую процедуру?
Вот еще более экстремальный пример, где я использую так много подзапросов Я превышать предел:
select
"SvHKeyId"=sh.KeyId,
"Scale"="Total",
"ScoreText"=convert(varchar(3),
(select sum(Resp) from SurvResp sr where sh.KeyId=sr.SvHKeyId
and QuestNum in (28,29,30,31,32,33,34,35,36,39,40,42,43,44,45,46) and Resp <> 5)
+
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37) <> 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38) <> 5
then
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37)
> (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37)
< (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37)
= (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
end)
else
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37) = 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38) = 5
then 0
else
(case
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37)
else 0
end)
end)
end)
+
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31) <> 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47) <> 5
then
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31)
> (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31)
< (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31)
= (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
end)
else
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31) = 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47) = 5
then 0
else
(case
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31)
else 0
end)
end)
end)
+
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46) <> 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48) <> 5
then
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46)
> (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46)
< (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46)
= (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
end)
else
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46) = 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48) = 5
then 0
else
(case
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46)
else 0
end)
end)
end)
),
"ScoreNum"=
(select sum(Resp) from SurvResp sr where sh.KeyId=sr.SvHKeyId
and QuestNum in (28,29,30,31,32,33,34,35,36,39,40,42,43,44,45,46) and Resp <> 5)
+
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37) <> 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38) <> 5
then
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37)
> (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37)
< (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37)
= (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
end)
else
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37) = 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38) = 5
then 0
else
(case
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38)
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=38) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=37)
else 0
end)
end)
end)
+
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31) <> 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47) <> 5
then
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31)
> (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31)
< (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31)
= (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
end)
else
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31) = 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47) = 5
then 0
else
(case
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47)
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=47) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=31)
else 0
end)
end)
end)
+
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46) <> 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48) <> 5
then
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46)
> (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46)
< (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46)
= (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
then
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
end)
else
(case
when
(select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46) = 5
and (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48) = 5
then 0
else
(case
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48)
when (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=48) = 5
then (select Resp from SurvResp sr where sh.KeyId=sr.SvHKeyId and sr.QuestNum=46)
else 0
end)
end)
end)
from
SurvHeader sh
where sh.KeyId=105101
«Я бы хотел получить чистое SQL-решение» - почему? то, что вы сейчас делаете, в значительной степени нечитаемо ... –
Возможно, чистый SQL - это не путь. Причина, по которой я хотел исследовать это, заключалась в том, что с помощью чистого SQL-решения процедура оценки становится независимой от приложения, поэтому она более переносима. – MaxPowers
И аналогично, вы можете сказать, что этот код SQL очень утомительный, перемещение логики в приложение создало бы решение, которое не зависит от механизма SQL ... Или, короче говоря, это сводится к следующему: нужна ли вам эта независимость ? –