WITH AS ,case when then else end 在sql中的运用

WITH FOOTNOTE_LIST (CARRIER_CD, TARIFF_CD, FOOTNOTE_CD, CATEGORY_NO, SEQUENCE_NO)
     AS (SELECT DISTINCT X.CARRIER_CD,
          X.TARIFF_CD,
          X.FOOTNOTE_CD,
          X.CATEGORY_NO,
          X.SEQUENCE_NO
      FROM  ${parSchema}FTNREC2_CATCTRL X 
      INNER JOIN ${parSchema}FTNBATCH Y
      ON X.FTNT_BTCH_SG = Y.FTNT_BTCH_SG
      WHERE  X.FOOTNOTE_CD = :ftntCode
                AND X.CATEGORY_NO = :categoryNumber
       AND Y.FTNT_BTCH_SG IN ( :batchSGs ))
       
   SELECT A.CARRIER_CD,
       A.TARIFF_CD,
       A.FOOTNOTE_CD,
       A.CATEGORY_NO,
       A.SEQUENCE_NO,
       A.FTNREC2_SG,
       A.CREATE_TS,
       A.BATCH_CI,
       A.BATCH_NO,
       A.LOCALE_1_TYPE,
       A.LOCALE_1_CD,
       A.LOCALE_2_TYPE,
       A.LOCALE_2_CD,
       A.EDOT_ACTION_TG,
       A.POSTPONE_ACTION_TG,
       CASE WHEN B.BATCH_STATUS_TG IS NULL THEN ‘F‘ ELSE B.BATCH_STATUS_TG END AS BATCH_STATUS_TG,
       B.FTNT_BTCH_SG,
       C.SEGMENT_ORDER_NO,
       C.FTNCAT_SG,
       C.RELATIONAL_IND,
       C.INBND_OUTBND_TG,
       C.DIRECTIONAL_TG
   FROM   FOOTNOTE_LIST T
     INNER JOIN ${parSchema}FTNREC2_CATCTRL A
       ON T.CARRIER_CD = A.CARRIER_CD
     AND T.TARIFF_CD = A.TARIFF_CD
     AND T.FOOTNOTE_CD = A.FOOTNOTE_CD
     AND T.CATEGORY_NO = A.CATEGORY_NO
     AND T.SEQUENCE_NO = A.SEQUENCE_NO
     LEFT OUTER JOIN ${parSchema}FTNBATCH B
      ON A.FTNT_BTCH_SG = B.FTNT_BTCH_SG
     LEFT OUTER JOIN ${parSchema}FTNSTR_CAT C
      ON A.FTNREC2_SG = C.FTNREC2_SG
     ORDER  BY A.CARRIER_CD,
      A.TARIFF_CD,
      A.FOOTNOTE_CD,
      A.CATEGORY_NO,
      A.SEQUENCE_NO,
      A.FTNREC2_SG,
      C.SEGMENT_ORDER_NO,
      A.CREATE_TS

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

使用WITH AS提高性能简化嵌套SQL

一.WITH AS的含义

WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会
被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数
据的部分。
特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是如果每个部分都去执行一遍的话,则成本太高,
所以可以使用WITH AS短语,则只要执行一遍即可。如果WITH AS短语所定义的表名被调用两次以上,则优化器会自动将
WITH AS短语所获取的数据放入一个TEMP表里,如果只是被调用一次,则不会。而提示materialize则是强制将WITH AS
短语里的数据放入一个全局临时表里。很多查询通过这种方法都可以提高速度。

二.使用方法

先看下面一个嵌套的查询语句:

select * from person.StateProvince where CountryRegionCode in          (select CountryRegionCode from person.CountryRegion where Name like ‘C%‘) 

上面的查询语句使用了一个子查询。虽然这条SQL语句并不复杂,但如果嵌套的层次过多,会使SQL语句非常难以阅
读和维护。因此,也可以使用表变量的方式来解决这个问题。

SQL语句如下:

declare @t table(CountryRegionCode nvarchar(3)) insert into @t(CountryRegionCode)  (select CountryRegionCode from person.CountryRegion where Name like ‘C%‘) 

select * from person.StateProvince where CountryRegionCode                      in (select * from @t) 

虽然上面的SQL语句要比第一种方式更复杂,但却将子查询放在了表变量@t中,这样做将使SQL语句更容易维护,但又
会带来另一个问题,就是性能的损失。由于表变量实际上使用了临时表,从而增加了额外的I/O开销,因此,表变量的方式
并不太适合数据量大且频繁查询的情况。为此,在SQL Server 2005中提供了另外一种解决方案,这就是公用表表达式(CTE),使用CTE,可以增加SQL语句的可维护性,同时,CTE要比表变量的效率高得多。

下面是CTE的语法:

[ WITH <common_table_expression> [ ,n ] ]
<common_table_expression>::=
        expression_name [ ( column_name [ ,n ] ) ]
    AS
        ( CTE_query_definition )

现在使用CTE来解决上面的问题,SQL语句如下:

with cr as (     select CountryRegionCode from person.CountryRegion where Name like ‘C%‘ ) 

select * from person.StateProvince where CountryRegionCode in (select * from cr) 

其中cr是一个公用表表达式,该表达式在使用上与表变量类似,只是SQL Server 2005在处理公用表表达式的方式上有
所不同。

在使用CTE时应注意如下几点:

1. CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,CTE将失效。如下面的SQL语句将无法正
常使用CTE:

with cr as (     select CountryRegionCode from person.CountryRegion where Name like ‘C%‘ ) select * from person.CountryRegion  -- 应将这条SQL语句去掉-- 使用CTE的SQL语句应紧跟在相关的CTE后面-- select * from person.StateProvince where CountryRegionCode in (select * from cr) 

2. CTE后面也可以跟其他的CTE,但只能使用一个with,多个CTE中间用逗号(,)分隔,如下面的SQL语句所示:

with cte1 as (     select * from table1 where name like ‘abc%‘ ), cte2 as (     select * from table2 where id > 20 ), cte3 as (     select * from table3 where price < 100 ) select a.* from cte1 a, cte2 b, cte3 c where a.id = b.id and a.id = c.id 

3. 如果CTE的表达式名称与某个数据表或视图重名,则紧跟在该CTE后面的SQL语句使用的仍然是CTE,当然,后面的SQL语句
使用的就是数据表或视图了,如下面的SQL语句所示:

--  table1是一个实际存在的表with table1 as (     select * from persons where age < 30 ) select * from table1  --  使用了名为table1的公共表表达式select * from table1  --  使用了名为table1的数据表

4. CTE 可以引用自身,也可以引用在同一WITH 子句中预先定义的CTE。不允许前向引用。

5. 不能在CTE_query_definition 中使用以下子句:

(1)COMPUTE 或COMPUTE BY

(2)ORDER BY(除非指定了TOP 子句)

(3)INTO

(4)带有查询提示的OPTION 子句

(5)FOR XML

(6)FOR BROWSE

6. 如果将CTE 用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾,如下面的SQL所示:

declare @s nvarchar(3) set @s = ‘C%‘ ;  -- 必须加分号with t_tree as (     select CountryRegionCode from person.CountryRegion where Name like @s ) select * from person.StateProvince where CountryRegionCode in (select * from t_tree) 

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

CASE命令有两种语句格式。
语法形式1:CASE expression
           WHEN expression_11 THEN expression_12
            …
           WHEN expression_n1 THEN expression_n2
           [ELSE expression_m]
           END
该语句的执行过程是:将CASE后面表达式的值与各WHEN子句中的表达式的值进行比较,如果两者相等,则返回THEN后的表达式的值,然后跳出CASE语句,否则返回ELSE子句中的表达式的值。ELSE子句是可选项。当CASE语句中不包含ELSE子句时,如果所有比较失败时,CASE语句将返回NULL。
【例】从数据表stud_info中,选取stud_id、grade,如果grade为“男”则输出“M”,如果为“女”输出“F”。
SELECT stud_id, sex=CASE gender
                     WHEN ’男’ THEN ’M’
                     WHEN ’女’ THEN ’F’
                   END
FROM stud_info
语法形式2:CASE WHEN condition_expression_1 THEN expression_1
             …
            WHEN condition_expression_n THEN expression_n
            [ELSE expression_m]
          END
该语句的执行过程是:首先测试WHEN后的条件表达式的值,如果其值为真,则返回THEN后面的表达式的值,否则测试下一个WHEN子句中的表达式的值,如果所有WHEN子句后的表达式的值都为假,则返回ELSE后的表达式的值,如果在CASE语句中没有ELSE子句,则CASE表达式返回NULL。
注意:CASE命令可以嵌套到SQL语句中。

【例】从stud_grade表中查询所有同学考试成绩情况,凡成绩为空者输出“未考”、小于60分输出“不及格”、60分至70分输出“及格”、70分至90分输出“良好”、大于或等于90分时输出“优秀”。
SELECT stud_id,name,score=CASE WHEN grade IS NULL THEN ’未考’
                             WHEN grade<60 THEN ’不及格’
                             WHEN grade>=60 AND grade<70 THEN ’及格’
                             WHEN grade>=70 AND grade<90 THEN ’良好’
                             WHEN grade>=90 THEN ’优秀’
                        END
FROM stud_grade

Case具有两种格式。简单Case函数和Case搜索函数。 
--简单Case函数 
CASE [object Object]sex 
WHEN ‘1‘ THEN ‘男‘ 
WHEN ‘2‘ THEN ‘女‘ 
ELSE ‘其他‘ END 
--Case搜索函数 
CASE WHEN sex = ‘1‘ THEN ‘男‘ 
WHEN sex = ‘2‘ THEN ‘女‘ 
ELSE ‘其他‘ END 

这两种方式,可以实现相同的功能。简单Case函数的写法相对比较简洁,但是和Case搜索函数相比,功能方面会有些限制,比如写判断式。 
还有一个需要注意的问题,Case函数只返回第一个符合条件的值,剩下的Case部分将会被自动忽略。
两者中可以根据不同的需求来选择

其它网友的实例:

Id     name        dept
1        aa          dept1
2        bb          dept1
3        cc           dept2

SELECT SUM(CASE decp WHEN ‘decp1‘ THEN 1 ELSE 0 end ) AS decp1,
sum(case decp when ‘decp2‘then 1 else 0 end)as decp2
FROM teacher

生成:

dept1     dept2

2             1

有一张表,里面有3个字段:语文,数学,英语。其中有3条记录分别表示语文70分,数学80分,英语58分,请用一条sql语句查询出这三条记录并按以下条件显示出来(并写出您的思路):
大于或等于80表示优秀,大于或等于60表示及格,小于60分表示不及格。
显示格式:
语文 数学 英语
及格 优秀 不及格
------------------------------------------
select
(case when 语文>=80 then ‘优秀‘
when 语文>=60 then ‘及格‘
else ‘不及格‘) as 语文,
(case when 数学>=80 then ‘优秀‘
when 数学>=60 then ‘及格‘
else ‘不及格‘) as 数学,
(case when 英语>=80 then ‘优秀‘
when 英语>=60 then ‘及格‘
else ‘不及格‘) as 英语,
from table

  CASE 可能是 SQL 中被误用最多的关键字之一。虽然你可能以前用过这个关键字来创建字段,但是它还具有更多用法。例如,你可以在 WHERE 子句中使用 CASE。

  首先让我们看一下 CASE 的语法。在一般的 SELECT 中,其语法如下:

  SELECT <myColumnSpec> =
      CASE
      WHEN <A> THEN <somethingA>
      WHEN <B> THEN <somethingB>
      ELSE <somethingE>
      END

  在上面的代码中需要用具体的参数代替尖括号中的内容。下面是一个简单的例子:

  USE pubs
      GO
      SELECT
      Title,
      ‘Price Range‘ =
      CASE
      WHEN price IS NULL THEN ‘Unpriced‘
      WHEN price < 10 THEN ‘Bargain‘
      WHEN price BETWEEN 10 and 20 THEN ‘Average‘
      ELSE ‘Gift to impress relatives‘
      END
      FROM titles
      ORDER BY price
      GO

  这是 CASE 的典型用法,但是使用 CASE 其实可以做更多的事情。比方说下面的 GROUP BY 子句中的 CASE:

  SELECT ‘Number of Titles‘, Count(*)
      FROM titles
      GROUP BY
      CASE
      WHEN price IS NULL THEN ‘Unpriced‘
      WHEN price < 10 THEN ‘Bargain‘
      WHEN price BETWEEN 10 and 20 THEN ‘Average‘
      ELSE ‘Gift to impress relatives‘
      END
      GO

  你甚至还可以组合这些选项,添加一个 ORDER BY 子句,如下所示:

  USE pubs
      GO
      SELECT
      CASE
      WHEN price IS NULL THEN ‘Unpriced‘
      WHEN price < 10 THEN ‘Bargain‘
      WHEN price BETWEEN 10 and 20 THEN ‘Average‘
      ELSE ‘Gift to impress relatives‘
      END AS Range,
      Title
      FROM titles
      GROUP BY
      CASE
      WHEN price IS NULL THEN ‘Unpriced‘
      WHEN price < 10 THEN ‘Bargain‘
      WHEN price BETWEEN 10 and 20 THEN ‘Average‘
      ELSE ‘Gift to impress relatives‘
      END,
      Title
      ORDER BY
      CASE
      WHEN price IS NULL THEN ‘Unpriced‘
      WHEN price < 10 THEN ‘Bargain‘
      WHEN price BETWEEN 10 and 20 THEN ‘Average‘
      ELSE ‘Gift to impress relatives‘
      END,
      Title
      GO

  注意,为了在 GROUP BY 块中使用 CASE,查询语句需要在 GROUP BY 块中重复 SELECT 块中的 CASE 块。

时间: 2024-08-01 05:20:29

WITH AS ,case when then else end 在sql中的运用的相关文章

SQL中的case when then else end用法

转载自 http://lj.soft.blog.163.com/blog/static/7940248120109215191358/ Case具有两种格式.简单Case函数和Case搜索函数. --简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END --Case搜索函数 CASE WHEN sex = '1' THEN '男' WHEN sex = '2' THEN '女' ELSE '其他' END 这两种方

【语法】SQL中的case when then else end用法-解决一个字段根据条件取不同值

Case具有两种格式.简单Case函数和Case搜索函数. --简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END --Case搜索函数 CASE WHEN sex = '1' THEN '男' WHEN sex = '2' THEN '女' ELSE '其他' END 这两种方式,可以实现相同的功能.简单Case函数的写法相对比较简洁,但是和Case搜索函数相比,功能方面会有些限制,比如写判断式. 还有一个需要

SQL中CASE 的用法 转载

sql语言中有没有类似C语言中的switch case的语句?? 没有,用case   when   来代替就行了.              例如,下面的语句显示中文年月 select getdate() as 日期,case month(getdate()) when 11 then '十一' when 12 then '十二' else substring('一二三四五六七八九十', month(getdate()),1) end+'月' as 月份 ===================

sql中对于case when...then...else...end的写法和理解

查询配件主数据表(tbl_part_base_info)的所有数据和配件是否有物料(物料表(tbl_material)中有配件主数据表的part_no,就表示有物料,反之,则表示没有物料),用sql中的case when...then...else...end来实现 第一种写法: select info.*,(case when material.part_no is null then '否' else '是' end) hasMaterial from tbl_part_base_info 

SQL中的条件判断语句(case when zhen if,ifnull)用法

一.case when then 适用于:sqlserver 和mysql case具有两种格式.简单case函数和case搜索函数.这两种方式,可以实现相同的功能.简单case函数的写法相对比较简洁,但是和case搜索函数相比,功能方面会有些限制,比如写判定式.还有一个需要注重的问题,case函数只返回第一个符合条件的值,剩下的case部分将会被自动忽略. --简单case函数case sex  when '1' then '男'  when '2' then '女’  else '其他' e

SQL中关键字Case的使用

本文非原创 它主要用来简化SQL表达式,在任何允许使用表达式的地方均可使用, 根据条件的不同返回不同的值. 注意:它不能单独执行,只能作为语句的一部分使用, 分为简单 case 表达式和搜索 case 表达式. 1.简单 case 表达式: 它是一个测试表达式与一组简单表达式进行比较,如果和某一个值相等, 则返回对应表达式的值. 语法: case 表达式 / 列名变量 when 测试值1 then 结果表达式1 when 测试值2 then 结果表达式2 …… else 结果表达式 end 例:

Sql中使用Case when

SELECT CASE WHEN Column IS NOT NULL THEN '情况1' ELSE '情况2' END AS '列名' , FROM dbo.Table

sql中的case when语句

1.在where子句中: 1 CREATE TABLE `hello`.`sometbl` ( 2 3 `id` INT NOT NULL AUTO_INCREMENT , 4 5 `a` VARCHAR(45) NULL , 6 7 `b` VARCHAR(45) NULL , 8 9 `c` VARCHAR(45) NULL , 10 11 PRIMARY KEY (`id`) , 12 13 UNIQUE INDEX `id_UNIQUE` (`id` ASC) ); 1 INSERT I

sql中case when的使用

运用场景:在表查询中总会遇到一些枚举定义的字段,如表:姓别(sex)字段,1为男,2为女.如果枚举过多很难记住对应的意思,都需要查看表注释,这样既麻烦有浪费时间.下面就距离对比case when的用法和好处. 1.普通查询 SELECT name,sex FROM person: 结果: 2.使用case when SELECT name,CASE sex WHEN 1 THEN '男' WHEN 2 THEN '女' ELSE '其他' END FROM person;