1

非常に反復的なSQLステートメントを作成するためのより良いアプローチを探しています。たとえば、PHP メソッドを使用してこれを実行できることはわかっていますが、純粋な 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
4

1 に答える 1

2

これらのリテラルのほとんどは、コードではなくデータである必要があります。これらの巨大なスイッチをデータにリファクタリングして、より単純なクエリで評価できるようにすることを強くお勧めします。その場合、「純粋な SQL」ソリューションははるかに実現可能であり、長期的にはパフォーマンスとメンテナンスの両方が向上します。Scoring参加して比較できる表でしょうか?

Scoring (Question, Answer, Result)は概念的な可能性の 1 つですが、単純化しすぎないことを願っています。

「FORTRAN はどの言語でも書ける」と言われているように。

T-SQLでさえ、そうです。

アップデート

これらの計算が既に行われており、現在のトランザクション内でテーブルを更新した場合は、まだコミットされていないため、再実行する必要はありません。このトランザクション内のすべてのクエリは、トランザクションで以前に更新された場合、このトランザクションの更新されたデータを取得します。

Sybase ASE トランザクションの詳細。

また、ストアド プロシージャでの作業をGO期待しないでください。トランザクション制御ではなく、IDE でバッチ区切りとして使用されます。

于 2013-05-10T17:47:23.910 に答える