1. 程式人生 > >oracle:case 語句使用(用於select子句的case語句中可以使用in這個函式)

oracle:case 語句使用(用於select子句的case語句中可以使用in這個函式)

case 語句帶有選擇效果知返回第一個條件滿足要求的語句,即語句一語句二都的判斷都為 true ,返回排在前面的。

case 的語法根據放置的位置不同而不同。

一.case 語句

複製程式碼
CASE SELECTOR
    WHEN EXPRESSION_1 THEN STATEMENT_1;
    [WHEN EXPRESSION_2 THEN STATEMENT_2;]
    [...]
    [ELSE STATEMENT_N+1 ;]
END CASE;
複製程式碼

這個是一般語句,注意 在then  後面需要 ; 分號,而且結束的時候  是 END CASE ;

CASE v_element
    
WHEN xx THEN yy; WHEN xxx THEN yyy; ELSE yyyy; END CASE;

當v_element 等於 xx 時,執行 yy 語句,如果很長可以 前後加 begin 和 end,判斷的條件是  v_element =xx ,xx是 具體值。

二.搜尋式 case 語句

複製程式碼
CASE 
    WHEN SEARCH_CONDITION_1 THEN STATEMENT_1;
    [WHEN SEARCH_CONDITION_1 THEN STATEMENT_2;]
    [...]
    [ELSE STATEMENT_N+1 ;
] END CASE;
複製程式碼
CASE 
    WHEN  v_element=xx  THEN yy;
    WHEN  v_element=xxx THEN  yyy;
    ELSE  yyyy;
END CASE;

按順序執行  選擇條件 ,可以是 < > = 等,然後執行後面的語句,遇到一個為true 時將停止。

三.case表示式

前兩個可以歸一類,起碼寫法上類似,用case 語句做表示式,意思是可以這麼寫:

複製程式碼
v_element:= CASE xx 
                            WHEN  x THEN y
                            
ELSE yy END; or select CASE xx WHEN x THEN y ELSE YY END ....
複製程式碼

就是把case 放在一條語句裡面, 刪除 END CASE 中的CASE 和 最後的 ; 分號,中間語句的分號也要刪掉。

可以把 case 至  end  看成一個值,最後面的分號是語句的要求,類似  a:= v ;  這樣的寫法。

四.NULLIF

這個是case 的變種函式,結構 :

NULLIF(xx,yy );

如果 xx = yy ,則返回 NULL, 如果不等啫返回 xx。

注意,在這函式中xx 引數不能為 NULL,即

NULLIF(NULL,0);

是錯的。

五.COALESCE

把表示式中的每個表示式與NULL比較,返回第一個非NULL 的表示式的值。結構如下:

COALSECE (x1,x2,...,xn);

寫法上可以將最後的寫為0 ,這麼就類似於CASE 中的else 選項。

=====================================

2023人閱讀 評論(0)收藏 舉報

Case when 的用法,簡單Case函式
簡單CASE表示式,使用表示式確定返回值.

  語法:

  CASE search_expression

  WHEN expression1 THEN result1

  WHEN expression2 THEN result2

  ...

  WHEN expressionN THEN resultN

  ELSE default_result

 搜尋CASE表示式,使用條件確定返回值.

  語法:

  CASE

  WHEN condition1 THEN result1

  WHEN condistion2 THEN result2

  ...

  WHEN condistionN THEN resultN

  ELSE default_result

  END

  例:

  select product_id,product_type_id,

  case

  when product_type_id=1 then 'Book'

  when product_type_id=2 then 'Video'

  when product_type_id=3 then 'DVD'

  when product_type_id=4 then 'CD'

  else 'Magazine'

  end

  from products 

這兩種方式,可以實現相同的功能。簡單Case函式的寫法相對比較簡潔,但是和Case搜尋函式相比,功能方面會有些限制,比如寫判斷式。

還有一個需要注意的問題,Case函式只返回第一個符合條件的值,剩下的Case部分將會被自動忽略。

比如說,下面這段SQL,你永遠無法得到“第二類”這個結果

 程式碼如下  
 

CASE WHEN col_1 IN ( 'a', 'b') THEN '第一類'

WHEN col_1 IN ('a')       THEN '第二類'

ELSE'其他' END
 

下面我們來看一下,使用Case函式都能做些什麼事情。

一,已知資料按照另外一種方式進行分組,分析。

有如下資料:(為了看得更清楚,我並沒有使用國家程式碼,而是直接用國家名作為Primary Key)

國家(country) 人口(population)

中國 600

美國 100

加拿大 100

英國 200

法國 300

日本 250

德國 200

墨西哥 50

印度 250

根據這個國家人口資料,統計亞洲和北美洲的人口數量。應該得到下面這個結果。

洲 人口

亞洲 1100

北美洲 250

其他 700

想要解決這個問題,你會怎麼做?生成一個帶有洲Code的View,是一個解決方法,但是這樣很難動態的改變統計的方式。

如果使用Case函式,SQL程式碼如下

 SELECT SUM(population),

CASE country

WHEN '中國'     THEN '亞洲'

WHEN '印度'     THEN '亞洲'

WHEN '日本'     THEN '亞洲'

WHEN '美國'     THEN '北美洲'

WHEN '加拿大' THEN '北美洲'

WHEN '墨西哥' THEN '北美洲'

ELSE '其他' END

FROM    Table_A

GROUP BY CASE country

WHEN '中國'     THEN '亞洲'

WHEN '印度'     THEN '亞洲'

WHEN '日本'     THEN '亞洲'

WHEN '美國'     THEN '北美洲'

WHEN '加拿大' THEN '北美洲'

WHEN '墨西哥' THEN '北美洲'

ELSE '其他' END;

同樣的,我們也可以用這個方法來判斷工資的等級,並統計每一等級的人數。SQL程式碼如下

SELECT

CASE WHEN salary <= 500 THEN '1'

WHEN salary > 500 AND salary <= 600 THEN '2'

WHEN salary > 600 AND salary <= 800 THEN '3'

WHEN salary > 800 AND salary <= 1000 THEN '4'

ELSE NULL END salary_class,

COUNT(*)

FROM    Table_A

GROUP BY

CASE WHEN salary <= 500 THEN '1'

WHEN salary > 500 AND salary <= 600 THEN '2'

WHEN salary > 600 AND salary <= 800 THEN '3'

WHEN salary > 800 AND salary <= 1000 THEN '4'

ELSE NULL END;

 二,用一個SQL語句完成不同條件的分組。

 有如下資料

國家(country) 性別(sex) 人口(population)

中國 1 340

中國 2 260

美國 1 45

美國 2 55

加拿大 1 51

加拿大 2 49

英國 1 40

英國 2 60

 按照國家和性別進行分組,得出結果如下

國家 男 女

中國 340 260

美國 45 55

加拿大 51 49

英國 40 60

 普通情況下,用UNION也可以實現用一條語句進行查詢。但是那樣增加消耗(兩個Select部分),而且SQL語句會比較長。

下面是一個是用Case函式來完成這個功能的例子

 程式碼如下 
SELECT country,

SUM( CASE WHEN sex = '1' THEN

population ELSE 0 END), --男性人口

SUM( CASE WHEN sex = '2' THEN

population ELSE 0 END)   --女性人口

FROM Table_A

GROUP BY country;

 這樣我們使用Select,完成對二維表的輸出形式,充分顯示了Case函式的強大。

 三,在Check中使用Case函式。

 在Check中使用Case函式在很多情況下都是非常不錯的解決方法。可能有很多人根本就不用Check,那麼我建議你在看過下面的例子之後也嘗試一下在SQL中使用Check。

 下面我們來舉個例子

公司A,這個公司有個規定,女職員的工資必須高於1000塊。如果用Check和Case來表現的話,如下所示

  程式碼如下 
CONSTRAINT check_salary CHECK

( CASE WHEN sex = '2'

THEN CASE WHEN salary > 1000

THEN 1 ELSE 0 END

ELSE 0 END ) 

如果單純使用Check,如下所示

 程式碼如下

CONSTRAINT check_salary CHECK

( sex = '2' AND salary > 1000 ) 

女職員的條件倒是符合了,男職員就無法輸入了。

例項

 程式碼如下

create table feng_test(id number, val varchar2(20);

insert into feng_test(id,val)values(1,'abcde');
insert into feng_test(id,val)values(2,'abc');
commit;

SQL>select * from feng_test;

id            val
-------------------
1             abcde
2             abc

SQL>select id
     , case when val like 'a%' then '1'
          when val like 'abcd%' then '2'
     else '999'
    end case
from feng_test;

id             case
---------------------
1                  1
2                  1
 

根據我自己的經驗我倒覺得在使用case when這個很像asp case when以在php swicth case開發關語句的用法,只要有點基礎知道我覺得在sql中的case when其實也很好理解

====================================================================

要寫個這樣的語句:

update A   
  set A.v1 = case when A.a='1' then (select B.v from B where B.id1=A.id1) else (select C.v from C where C.id2=A.id2) end
where exists
  case when A.a='1' then (select * from B where B.id1=A.id1) else (select * from C where C.id2=A.id2) end


update A   
  set A.v1 = case when A.a='1' then (select B.v from B where B.id1=A.id1) else (select C.v from C where C.id2=A.id2) end
where
  case when A.a='1' then (exists (select * from B where B.id1=A.id1)) else (exists (select * from C where C.id2=A.id2)) end


但是exists無論是寫在case外還在裡,都報錯,難道case就不能結合exists用嗎?

update A   
  set A.v1 = (select B.v from B where B.id1=A.id1)
where
  exists  (select * from B where B.id1=A.id1)

原先是這樣的語句,exists是為了保護下,避免把null更新進去,後來又增加了條件,根據A表中某個欄位值判斷,決定從哪張表中取資料,這樣,set部分用case when沒問題,但是在where中,exists就有問題了,換個思路?怎麼換?提示下?

回答:

拆成兩句:


UPDATE a
SET a.v1=(SELECT b.v FROM b WHERE b.id1=a.id1)
WHERE a.id1 IN (SELECT b.id1 FROM b)
AND a.a=1
/

UPDATE a
SET a.v1=(SELECT c.v FROM c WHERE c.id2=a.id2)
WHERE a.id2 IN (SELECT c.id2 FROM c)
AND a.a<>1
/

或是

update A   
  set A.v1 = case when A.a='1' then (select B.v from B where B.id1=A.id1) else (select C.v from C where C.id2=A.id2) end
where exists (SELECT 1 from B WHERE B.id1=A.id1 AND A.a='1')
      OR
      exists (SELECT 1 from C WHERE C.id2=A.id2 AND NVL(A.a,'0')<>'1')

http://www.itpub.net/forum.php?mod=viewthread&tid=1046495&highlight=

=======================================================================

如下:
select * from tab1 t where t.colum1 in(case t.flag when 1 then '''001'',''002''' else '''001'',''002''' end)


如上描述,假如tab1表中有多條記錄,並且colum1(欄位資料型別:varchar2)欄位中有為001與002的值 ,可用以上語句卻查詢不出一條記錄?我測試了一下: select case t.flag when 1 then '''001'',''002''' else '''001'',''002''' end from dual 返回的是:
字串 '001','002' 按理說是符合 in 條件查詢的。麻煩各位幫忙看看問題出在哪裡。或是有更好的方法還望不吝賜教啊!(在oracle資料庫中測試的)

注:case t.flag when 1 then '''001'',''002''' else '''001'',''002''' end 紅色部分的值是用java程式從配置檔案中讀取出來的 問題補充:orcale字串拼接不支援“+”的吧,這樣式不行的,'''001''' + ','+ '''002'''  這些資料時通過一個方法返回的字串。不過我改成“||”拼接還是查不出記錄in('001','002')這樣只就可以,加上case 語句就不行了。。。

fengxiaofeng 寫道 select * from tab1 t where t.colum1 in(case t.flag when 1 then '''001''' + ','+ '''002''' else '''001''' + ','+ '''002''' end)

============================================
46525人閱讀 評論(1)收藏 舉報

目錄(?)[+]

 CASE 語句

CASE selector
   WHEN value1 THEN action1;
   WHEN value2 THEN action2;
   WHEN value3 THEN action3;
   …..
   ELSE actionN;
END CASE;

CASE表示式

DECLARE
   temp VARCHAR2(10);
   v_num number;
BEGIN
   v_num := &i;
   temp := CASE v_num
     WHEN 0 THEN 'Zero'
      WHEN 1 THEN 'One'
     WHEN 2 THEN 'Two'
   ELSE
       NULL
   END;
   dbms_output.put_line('v_num = '||temp);
END;
/

CASE搜尋語句

CASE
   WHEN (boolean_condition1) THEN action1;
   WHEN (boolean_condition2) THEN action2;
   WHEN (boolean_condition3) THEN action3;
   ……
   ELSE    actionN;
END CASE;

CASE搜尋表示式 

DECLARE
   a number := 20;
   b number := -40;
   tmp varchar2(50);
BEGIN
   tmp := CASE
              WHEN (a>b) THEN 'A is greater than B'
              WHEN (a<b) THEN 'A is less than B'
              ELSE
              'A is equal to B'
              END;
   dbms_output.put_line(tmp);
END;
/

SELECT CASE WHEN 的用法

select 與 case結合使用最大的好處有兩點,一是在顯示查詢結果時可以靈活的組織格式,二是有效避免了多次對同一個表或幾個表的訪問。下面舉個簡單的例子來說明。例如表 students(id, name ,birthday, sex, grade),要求按每個年級統計男生和女生的數量各是多少,統計結果的表頭為,年級,男生數量,女生數量。如果不用select case when,為了將男女數量並列顯示,統計起來非常麻煩,先確定年級資訊,再根據年級取男生數和女生數,而且很容易出錯。用select case when寫法如下:
SELECT   grade, COUNT (CASE WHEN sex = 1 THEN 1      /*sex 1為男生,2位女生*/
                                            ELSE NULL
                                            END) 男生數,
                            COUNT (CASE WHEN sex = 2 THEN 1
                                            ELSE NULL
                                            END) 女生數
    FROM students GROUP BY grade;

========================================================
Oracle SQL巢狀CASE WHEN
2013-04-17 09:05:41     我來說兩句       作者:dacoolbaby
收藏  我要投稿
Oracle SQL巢狀CASE WHEN 嘗試了一下,Oracle CASE WHEN 是可以支援巢狀使用的。 雖然看起來比較噁心,但是還是挺有用的。 Sql程式碼   select case            when (1 = 1) then                 case when(2=3) then                          'A'                     else  'K'                     end            else             'b'          end     from dual;   這裡可以正常地輸出K,表示第二次的CASE WHEN能夠發揮作用。

參考:

百度

oracle+select+case+when+then+else

oracle select case when then else

另見: