ホームページ > データベース > mysql チュートリアル > SQL Server 2008 の WHERE 句内で CASE ステートメントを正しく使用するにはどうすればよいですか?

SQL Server 2008 の WHERE 句内で CASE ステートメントを正しく使用するにはどうすればよいですか?

Mary-Kate Olsen
リリース: 2025-01-11 09:54:42
オリジナル
768 人が閲覧しました

How Can I Correctly Use CASE Statements Within WHERE Clauses in SQL Server 2008?

SQL Server 2008 の WHERE 句における CASE ステートメントの問題への対処

SQL Server 2008 の WHERE 句内で CASE ステートメントを使用すると、問題が発生する可能性があります。 次のクエリは、一般的な問題を例示しています:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

<code class="language-sql">SELECT

    tl.storenum 'Store #',

    co.ccnum 'FuelFirst Card #',

    co.dtentered 'Date Entered',

    CASE st.reasonid

        WHEN 1 THEN 'Active'

        WHEN 2 THEN 'Not Active'

        WHEN 0 THEN st.ccstatustypename

        ELSE 'Unknown'

    END 'Status',

    CASE st.ccstatustypename

        WHEN 'Active' THEN ' '

        WHEN 'Not Active' THEN ' '

        ELSE st.ccstatustypename

    END 'Reason',

    UPPER(REPLACE(REPLACE(co.personentered,'RT\\',''),'RACETRAC\\','')) 'Person Entered',

    co.comments 'Comments or Notes'

FROM

    comments co

    INNER JOIN cards cc ON co.ccnum=cc.ccnum

    INNER JOIN customerinfo ci ON cc.customerinfoid=ci.customerinfoid

    INNER JOIN ccstatustype st ON st.ccstatustypeid=cc.ccstatustypeid

    INNER JOIN customerstatus cs ON cs.customerstatuscd=ci.customerstatuscd

    INNER JOIN transactionlog tl ON tl.transactionlogid=co.transactionlogid

    LEFT JOIN stores s ON s.StoreNum = tl.StoreNum

WHERE

    CASE LEN('TestPerson')

        WHEN 0 THEN co.personentered  = co.personentered

        ELSE co.personentered LIKE '%TestPerson'

    END

    AND cc.ccnum = CASE LEN('TestFFNum')

        WHEN 0 THEN cc.ccnum

        ELSE 'TestFFNum'

    END

    AND CASE LEN('2011-01-09 11:56:29.327')

        WHEN 0 THEN co.DTEntered = co.DTEntered

        ELSE

            CASE LEN('2012-01-09 11:56:29.327')

                WHEN 0 THEN co.DTEntered >= '2011-01-09 11:56:29.327'

                ELSE co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327'

            END

    END

    AND tl.storenum < 699

ORDER BY tl.StoreNum</code>

ログイン後にコピー

解決策: ブール論理によるリファクタリング

中心的な問題は、WHERE 句の条件ロジック内で直接 CASE ステートメントが不適切に使用されていることにあります。 CASE 式は値を生成する必要があります。それらがすべての状態であるべきではありません。

この解決策には、AND および OR 演算子を使用して CASE ステートメントを同等のブール ロジックに置き換えることが含まれます。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<code class="language-sql">SELECT

    tl.storenum 'Store #',

    co.ccnum 'FuelFirst Card #',

    co.dtentered 'Date Entered',

    CASE st.reasonid

        WHEN 1 THEN 'Active'

        WHEN 2 THEN 'Not Active'

        WHEN 0 THEN st.ccstatustypename

        ELSE 'Unknown'

    END 'Status',

    CASE st.ccstatustypename

        WHEN 'Active' THEN ' '

        WHEN 'Not Active' THEN ' '

        ELSE st.ccstatustypename

    END 'Reason',

    UPPER(REPLACE(REPLACE(co.personentered,'RT\\',''),'RACETRAC\\','')) 'Person Entered',

    co.comments 'Comments or Notes'

FROM

    comments co

    INNER JOIN cards cc ON co.ccnum=cc.ccnum

    INNER JOIN customerinfo ci ON cc.customerinfoid=ci.customerinfoid

    INNER JOIN ccstatustype st ON st.ccstatustypeid=cc.ccstatustypeid

    INNER JOIN customerstatus cs ON cs.customerstatuscd=ci.customerstatuscd

    INNER JOIN transactionlog tl ON tl.transactionlogid=co.transactionlogid

    LEFT JOIN stores s ON s.StoreNum = tl.StoreNum

WHERE

    (LEN('TestPerson') = 0 AND co.personentered = co.personentered) OR (LEN('TestPerson') > 0 AND co.personentered LIKE '%TestPerson')

    AND ((LEN('TestFFNum') = 0 AND cc.ccnum = cc.ccnum) OR (LEN('TestFFNum') > 0 AND cc.ccnum = 'TestFFNum'))

    AND ((LEN('2011-01-09 11:56:29.327') = 0 AND co.DTEntered = co.DTEntered) OR (LEN('2012-01-09 11:56:29.327') = 0 AND co.DTEntered >= '2011-01-09 11:56:29.327') OR (co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327'))

    AND tl.storenum < 699

ORDER BY tl.StoreNum;</code>

ログイン後にコピー

パフォーマンスの強化

この修正されたクエリは正しく機能しますが、パフォーマンスはさらに向上する可能性があります。

  • ネストを減らす: 深くネストされた OR 条件は効率が低下する可能性があります。 代替のクエリ構造を検討してください (例: 個別の検索条件に UNION ALL を使用する)。
  • インデックス作成: WHERE 句で頻繁に使用される列 (co.personenteredcc.ccnumco.DTEnteredtl.storenum など) にインデックスが存在することを確認します。
  • パラメータ化: これらの「テスト」値が変数の場合は、クエリ解析の繰り返しを避けるためにパラメータ化されたクエリを使用します。

これらの点に対処することで、より効率的で読みやすい SQL クエリを作成できます。

以上がSQL Server 2008 の WHERE 句内で CASE ステートメントを正しく使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート