小説はcase~

11871 ワード

caseというキーワードは、使うところが少なくありません~ほとんどの用途は以下のように応用されています
DECLARE @i INT = 3

SELECT  CASE @i
          WHEN 1 THEN 1
          WHEN 2 THEN 2
          WHEN 3 THEN 3
        END AS  1;

 1
-----------
3


DECLARE @Hour INT = DATEPART(hh,GETDATE())

SELECT CASE WHEN @Hour BETWEEN 7 AND 12 THEN ' '
            WHEN @Hour >= 12 AND @Hour < 18 THEN ' '
            WHEN @Hour > 18 AND @Hour < 24 THEN ' '
            ELSE ' ' END AS  


 
------
 
            

这已经用得炉火纯青じòぴé的小伙伴请蔑视我.
補足すると、最初のクエリーと2番目のクエリーの違いは、2番目のクエリーにelseがあり、このelseは一致しない値を処理するために使用されます.elseの処理がなければ,最初の例の@i=4のように式はNullを返す.
 
もう一つの例をあげて、簡単に従業員表を作成して、caseを使っていくつかのカスタムルールを作ることができます.ここは部門別で、優先は秘書処で、それから開発部で、それから人事部で、最後に他の部門は前後を問わず、入社時間によって順番を決めます.
CREATE TABLE #Employee (ID INT IDENTITY(1,1),DeparmentName NVARCHAR(50),Name NVARCHAR(50),EntryDate DATETIME)

INSERT INTO #Employee
        ( DeparmentName, Name, EntryDate )
VALUES  ( N' ',N'Joey', '2015-04-12'),
        ( N' ',N'John', '2013-04-23'),
        ( N' ',N'Mery', '2012-03-17'),
        ( N' ',N'Anna', '2014-05-07'),
        ( N' ',N'Dave', '2011-01-12'),
        ( N' ',N'Alex', '2012-03-03')

SELECT *
    FROM #Employee
    ORDER BY CASE DeparmentName WHEN ' ' THEN 1
                                WHEN ' ' THEN 2
                                WHEN ' ' THEN 3
                                ELSE 4 END,EntryDate
     

ID          DeparmentName                                      Name                                               EntryDate
----------- -------------------------------------------------- -------------------------------------------------- -----------------------
5                                                            Dave                                               2011-01-12 00:00:00.000
3                                                            Mery                                               2012-03-17 00:00:00.000
6                                                            Alex                                               2012-03-03 00:00:00.000
2                                                            John                                               2013-04-23 00:00:00.000
4                                                            Anna                                               2014-05-07 00:00:00.000
1                                                            Joey                                               2015-04-12 00:00:00.000

 
caseを使うには文法の上での使用に注意しなければなりません.まず、オンラインドキュメントの2つです.
1 caseのネスト上限は10です
2以下この栗は0除のエラーを実行します.1/valueには0があるので、実行時に式の値に注意する必要があり、集約後の値やwhenの順序に依存してはいけないことに注意してください.これは意外な結果になります.
WITH Data (value) AS 
( 
SELECT 0 
UNION ALL 
SELECT 1 
) 
SELECT 
   CASE 
      WHEN MIN(value) <= 0 THEN 0 
      WHEN MAX(1/value) >= 100 THEN 1 
   END 
FROM Data ;

3 thenの後の式に注意してください.例えば、前のクエリ文を変更します.thenの後のデータ型の暗黙的な変換に失敗すると、次のエラーが表示されるので、これは注意してください.
SELECT *
    FROM #Employee
    ORDER BY CASE DeparmentName WHEN ' ' THEN 1    
                                WHEN ' ' THEN 'a'  -- 'a'
                                WHEN ' ' THEN 3
                                ELSE 4 END,EntryDate


  24516112  
  varchar   'a'   int

4 thenの後だけでなくwhenの後の値もデータ型の一致に注意する必要がある.上記の例は開発部を1('1')に変更すれば誤りも成立する.
5 caseで関数を使用すると、毎回再呼び出しされる特殊な場合もあります.例えば次の例
DECLARE @i INT = 1,
        @j INT

DECLARE @T AS TABLE (I INT)
WHILE @i < 100
BEGIN
    SELECT @j = CASE WHEN CAST(RAND()*10 AS INT)%3 = 0 THEN 0
                  WHEN CAST(RAND()*10 AS INT)%3 = 1 THEN 1
                  WHEN CAST(RAND()*10 AS INT)%3 = 2 THEN 2 END,
           @i = @i + 1
    INSERT INTO @T
            ( I )
    VALUES  ( @j )
END 
SELECT I,COUNT(*)
    FROM @T
    GROUP BY I

I           
----------- -----------
NULL        27
0           34
1           24
2           14

 
(Null???Nullはどうして出てくるの??rand(*)*10%3(0,1,2)の3つしかない場合がありますね!!俺をからかってるのか?
実はこの見本紙なので、文を見てみると、caseの中には、一つもマッチしていません.case whenの中の条件を一度判断する必要があります.だから、毎回Rand(*)*10という表現を実行して、1,2,3の値ではない太い線を作ることができます.安定するには、このように変更します.
DECLARE @i INT = 1,
        @j INT

DECLARE @T AS TABLE (I INT)
WHILE @i < 100
BEGIN
    SELECT @j = CAST(RAND()*10 AS INT) ,
           @j = CASE @j%3 WHEN 0 THEN 0
                  WHEN  1 THEN 1
                  WHEN  2 THEN 2 END,
           @i = @i + 1
    INSERT INTO @T
            ( I )
    VALUES  ( @j )
END 
SELECT I,COUNT(*)
    FROM @T
    GROUP BY I


I           
----------- -----------
0           40
1           24
2           35

ほら!これでNullはなくなりました~
 
そして~これで終わりです