sql总结的事例

 事例一:排序

ORDER BY子句可包括未出现在此选择列表的项目.然而,如果指定SELECT DISTINCT,则排序列必定出现在选择列表中.

错误的语句:SELECT DISTINCT 书名 FROM tb_BookStore ORDER BY 现存数量

正确的语句:SELECT DISTINCT (书名),现存数量 FROM tb_BookStore ORDER BY 现存数量

(2)

gold是等级   expire_date是到期时间   
    
根据前面的查询是按等级后再按到期时间,这样的话高等级的过期的人就在低等级没过期的人的前面.   
    
现在要做成   过期的都要到后面显示   无论等级是多少   而没过期的还是正常按等级及到期时间排列  

Create   Table   #TEST  
  (ID   Int,  
    gold Int,  
    expire_date DateTime)  
  Insert   #TEST   Select   1,2,'2006-06-30'  
  Union   All   Select   2,3,'2006-06-30'  
  Union   All   Select   3,5,'2006-05-30'  
  Union   All   Select   4,6,'2006-06-12'  
  Union   All   Select   5,10,'2006-07-30'  
  Union   All   Select   6,1,'2006-08-30'  
  Union   All   Select   6,1,'2008-08-30' 
  Union   All   Select   6,1,'2009-08-30' 

select   top   100   *   from   [#TEST]   order   by   (Case   When   expire_date>=GetDate()   Then  0   Else  1  End),   gold   desc,expire_date   desc

事例2:charindex

B=(1,11,2,22,3)

select   *   from   table   where     
charindex(',1,',','+B+',')>0   or   charindex(',2,',','+B+',')>0   
or   charindex(',3,',','+B+',')>0

(2)

  INSERT   @t   SELECT   '消费电子'  
  UNION   ALL   SELECT   '消费电子   '  
  UNION   ALL   SELECT   ',消费电子,'  
   
  select   *   from   @t   where   nkey='消费电子'  
  /*--   结果  
  id                     nkey  
  -----------   ----------  
  1                       消费电子  
  2                       消费电子    
  --*/  
   
  select   *,   ','+'消费电子'+','   from   @t   where   charindex(','+'消费电子'+',',','+nkey+',')>0  
  /*--   结果  
  id                     nkey                
  -----------   ----------   ----------  
  1                       消费电子               ,消费电子,  
  3                       ,消费电子,           ,消费电子,  
   
  (2   行受影响)  
  --*/  
   
  select   *   from   @t   where   ','+'消费电子'+','=','+nkey+','  
  /*--   结果  
  id                     nkey  
  -----------   ----------  
  1                       消费电子  
   
  (1   行受影响)  
  --*/

 charindex(','+'消费电子'+',',','+nkey+',')>0  
  这个是包含关系  
   
   
  ','+'消费电子'+','=','+nkey+','  
  这个是完全匹配关系.

事例3:replace

 REPLACE   (   'string_expression1'   ,   'string_expression2'   ,   'string_expression3'   )  

示例  
  下例用   xxx   替换   abcdefghi   中的字符串   cde。  
  SELECT   REPLACE('abcdefghicde','cde','xxx')  
  GO  
   
  下面是结果集:  
   
  ------------  
  abxxxfghixxx  
  (1   row(s)   affected)

事例4:case when

CASE 具有两种格式:
(1)简单 CASE 函数将某个表达式与一组简单表达式进行比较以确定结果。
(2)CASE 搜索函数计算一组布尔表达式以确定结果。两种格式都支持可选的 ELSE 参数。

语法
简单 CASE 函数:

CASE input_expression
    WHEN when_expression THEN result_expression
        [ ...n ]
    [
        ELSE else_result_expression
    END

CASE 搜索函数:

select case StatusValue
when '0' then (select top 1 字段名 from work)
when '1' then (select top 1 字段名 from Notice)
end
from CommonStatusDict

create table tb(id int ,class varchar)--class种类就只有三种,如果不固定就需要存储过程来实现
insert tb
select 1,'a' union all
select 1,'a' union all
select 1,'b' union all
select 1,'c' union all
select 2,'a' union all
select 2,'b' union all
select 2,'b'
select * from tb

想查找出按id分组得到的 a  ,b  ,c 的数量
  如下
id   a   b    c
1   2   1     1
2   1   2    0

select 
 id,
 a=sum(case class when 'a' then 1 else 0 end),
 b=sum(case class when 'b' then 1 else 0 end),
 c=sum(case class when 'c' then 1 else 0 end)
from 
 tb
group by
 id

事例5:datediff

要查询9 月份的数据中的任意时间段,可能是一个月的,也可能是1日到15日的

select   *   from   tabname   where   datediff(month,colname,'2006-09-01')=0

事例6:convert

SQL中CONVERT转化函数的用法
SQL中CONVERT转化函数的用法

CONVERT的使用方法:

格式:
CONVERT(data_type,expression[,style])

说明:
此样式一般在时间类型(datetime,smalldatetime)与字符串类型(nchar,nvarchar,char,varchar)
相互转换的时候才用到.

例子:
SELECT CONVERT(varchar(30),getdate(),101) now
结果为
now
---------------------------------------
09/15/2001

/

style数字在转换时间时的含义如下

-------------------------------------------------------------------------------------------------
Style(2位表示年份) | Style(4位表示年份) | 输入输出格式
-------------------------------------------------------------------------------------------------
- | 0 or 100 | mon dd yyyy hh:miAM(或PM)
-------------------------------------------------------------------------------------------------
1 | 101 | mm/dd/yy
-------------------------------------------------------------------------------------------------
2 | 102 | yy-mm-dd
-------------------------------------------------------------------------------------------------
3 | 103 | dd/mm/yy
-------------------------------------------------------------------------------------------------
4 | 104 | dd-mm-yy
-------------------------------------------------------------------------------------------------
5 | 105 | dd-mm-yy
-------------------------------------------------------------------------------------------------
6 | 106 | dd mon yy
-------------------------------------------------------------------------------------------------
7 | 107 | mon dd,yy
-------------------------------------------------------------------------------------------------
8 | 108 | hh:mm:ss
-------------------------------------------------------------------------------------------------
- | 9 or 109 | mon dd yyyy hh:mi:ss:mmmmAM(或PM)
-------------------------------------------------------------------------------------------------
10 | 110 | mm-dd-yy
-------------------------------------------------------------------------------------------------
11 | 111 | yy/mm/dd
-------------------------------------------------------------------------------------------------
12 | 112 | yymmdd
-------------------------------------------------------------------------------------------------
- | 13 or 113 | dd mon yyyy hh:mi:ss:mmm(24小时制)
-------------------------------------------------------------------------------------------------
14 | 114 | hh:mi:ss:mmm(24小时制)
-------------------------------------------------------------------------------------------------
- | 20 or 120 | yyyy-mm-dd hh:mi:ss(24小时制)
-------------------------------------------------------------------------------------------------
- | 21 or 121 | yyyy-mm-dd hh:mi:ss:mmm(24小时制)

例如当前时间为:2005-9-12 13:20:00

我要取其中的:2005-9-12

select convert(char(10),'2005-9-12 13:20:00',120)

事例7:区分大小写

create     table   tab(idd   int,address   varchar(20)   COLLATE   Chinese_PRC_CS_AS)  
  insert   tab   values(1,'aaaa')  
  insert   tab   values(2,'AAAA')  
  insert   tab   values(3,'aaaa')  
  insert   tab   values(4,'aAAa')  
  insert   tab   values(5,'aAAA')  
   
  select   *   from   tab   where   address   =   'aaaa'   COLLATE   Chinese_PRC_CS_AS   
  select   *   from   tab   where   address   =   'aAAa'   COLLATE   Chinese_PRC_CS_AS   
  drop   table   tab

事例8:取n到m条记录的语句   

   1.  
  select   top   m   *   from   tablename   where   id   not   in   (select   top   n   *   from   tablename)  
   
  2.  
  select   top   m   *   into   临时表(或表变量)   from   tablename   order   by   columnname   --   将top   m笔插入  
  set   rowcount   n  
  select   *   from   表变量   order   by   columnname   desc  
   
  3.  
  select   top   n   *   from    
  (select   top   m   *   from   tablename   order   by   columnname)   a  
  order   by   columnname   desc  
   
   
  4.如果tablename里没有其他identity列,那么:  
  select   identity(int)   id0,*   into   #temp   from   tablename  
   
  取n到m条的语句为:  
  select   *   from   #temp   where   id0   >=n   and   id0   <=   m  
   
  如果你在执行select   identity(int)   id0,*   into   #temp   from   tablename这条语句的时候报错,那是因为你的DB中间的select   into/bulkcopy属性没有打开要先执行:  
  exec   sp_dboption   你的DB名字,'select   into/bulkcopy',true  
   
   
  5.如果表里有identity属性,那么简单:  
  select   *   from   tablename   where   identitycol   between   n   and   m

事例9:stuff

sql替换表中某些字.
比如 titles表中有id,name ,age3个字段
我想根据name字段来修改id字段,并且在id字段前面添加'ABC'


update 表名 set id=stuff(id,1,3,'abc') where name='名称'

事例10;连接字段输出

select Name,Description from Students,现在我想把Name,Description作为一个字段Detail输出,请问如何写?

select Name+Description as Detail from Students

事例11;拷贝表格

建立表格:

CREATE   TABLE   tb(ID   int,   名称   NVARCHAR(30),   备注   NVARCHAR(1000))  
  INSERT   tb       SELECT   1,'DDD',1  
  UNION     ALL                 SELECT   1,'5100','D'  
  UNION     ALL                 SELECT   1,'5200','E'  
   
  也可以这样:  
  CREATE   TABLE   tb1(ID   int,   名称   NVARCHAR(30),   备注   NVARCHAR(1000))  
  INSERT   TB1   (ID,名称,备注)VALUES(1,'DDD',1)  
  INSERT   TB1   (ID,名称,备注)VALUES(1,'5100','D')  
  INSERT   TB1   (ID,名称,备注)VALUES(1,'5200','E')

(2) 

table_new 原来已经存在且字段和顺序和table_old 完全一样

insert into table_new  select * from table_old

 如不一样修改对应字段即可,注意插入数据主键问题..

    insert into table_new(column1,column2)
    select column1,column2 from table_old

或者

(3)数据库中不存在table_new表 很简单

   select * into table_new from table_old

 事例12:union(all)

  select   *   from   A  
  union    
  select   *   from   B  
   
   
   
  --不合并重复行  
  select   *   from   A  
  union   all  
  select   *   from   B  
   
   
  --如果要对字段进行排序  
  select   *  
  from   (  
  select   id,...   from   A  
  union   all  
  select   id,...   from   B  
  )   t  
  order   by   ID  

事例13:模糊查询

like '%[AB]%'
只要满足字符串中包含A或者B或者AB就选出,顺序不限,这样会选出很多

like '%[AB]%'这样会选出如下组合
AB
BA
ACCCC
BCCCCC
ACB
BCA

事例14:别名

1:   select   *   from    
  2:   (  
  3:   select   yw_shangsi,   sum(case   yw_del   when   1   then   1   else   0   end)   as   num    
  4:   from   yewuyuan    
  5:   group   by   yw_shangsi   having   sum(case   yw_del   when   1   then   1   else   0   end)>=3  
  6:   )  
   
  服务器:   消息   170,级别   15,状态   1,行   6  
  第   6   行:   ')'   附近有语法错误。   
    1:   select   *   from    
  2:   (  
  3:   select   yw_shangsi,   sum(case   yw_del   when   1   then   1   else   0   end)   as   num    
  4:   from   yewuyuan    
  5:   group   by   yw_shangsi   having   sum(case   yw_del   when   1   then   1   else   0   end)>=3  
  6:   )   aa  
   
  这样就没问题了

内嵌视图,要定义别名才能在select   后作为表使用

事例15:动态sql语句

动态sql语句基本语法
1 :普通SQL语句可以用Exec执行

eg:   Select * from tableName
         Exec('select * from tableName')
         Exec sp_executesql N'select * from tableName'    -- 请注意字符串前一定要加N

2:字段名,表名,数据库名之类作为变量时,必须用动态SQL

eg:  
declare @fname varchar(20)
set @fname = 'FiledName'
Select @fname from tableName              -- 错误,不会提示错误,但结果为固定值FiledName,并非所要。
Exec('select ' + @fname + ' from tableName')     -- 请注意 加号前后的 单引号的边上加空格

当然将字符串改成变量的形式也可
declare @fname varchar(20)
set @fname = 'FiledName' --设置字段名

declare @s varchar(1000)
set @s = 'select ' + @fname + ' from tableName'
Exec(@s)                -- 成功
exec sp_executesql @s   -- 此句会报错

 

declare @s Nvarchar(1000)  -- 注意此处改为nvarchar(1000)
set @s = 'select ' + @fname + ' from tableName'
Exec(@s)                -- 成功    
exec sp_executesql @s   -- 此句正确

3. 输出参数
declare @num int,
        @sqls nvarchar(4000)
set @sqls='select count(*) from tableName'
exec(@sqls)
--如何将exec执行结果放入变量中?

declare @num int,
               @sqls nvarchar(4000)
set @sqls='select @a=count(*) from tableName '
exec sp_executesql @sqls,N'@a int output',@num output
select @num

事例16:子查询与内联查询

create table #123(id int,N1 int,N2 int)
insert into #123
select 1,10,20
union all select 2,5,5
union all select 3,5,5

create table #234(id int,pid int,N1 int,N2 int)
insert into #234
select 1,1,10,20
union all select 2,1,5,5
--union all select 2,1,5,5(如果加入这一行就会出错)

select id ,(select pid from #234 where aaa.id=id) as bbb
from #123  as aaa
group by id

1 1
2 1
3 NULL

select aaa.id,bbb.pid
from #123 as aaa ,#234 as bbb
where aaa.id=bbb.id

1 1
2 1

这两个语句没有可比性啊, 因为两个语句并不等效.
第1个查询得到的结果是left join的效果, 而且还要保证匹配的id唯一才不会导致查询出错
第2个语句是inner join的结果, 只有匹配的记录才会出现在结果集中, 而且对id是否唯一没有任何要求

(邹老大对此的解释)


事例17:最常用的还有几个函数(之前介绍过几个)
(1)ISNULL
使用指定的替换值替换 NULL。
语法
ISNULL ( check _ expression , replacement_value )
参数
check_expression
将被检查是否为 NULL的表达式。 check_expression 可以是任何类型的。
replacement_value
check_expression 为 NULL时将返回的表达式。 replacement_value 必须与 check_expresssion 具有相同的类型。
返回类型
返回与 check_expression 相同的类型。
注释
 
如果 check_expression 不为 NULL,那么返回该表达式的值;否则返回 replacement_value
如果一个书名的价格是 NULL,那么在结果集中显示的价格为 0.00,而不是NULL的返回原值
ISNULL(price, 0.00)

(2)

LTRIM ( character_expression )删除字符变量中的起始空格

RTRIM ( character_expression ) 删除字符变量中的尾随空格
 
(3)
SUBSTRING ( expression , start , length )
参数
expression
是字符串、二进制字符串、text、image、列或包含列的表达式。不要使用包含聚合函数的表达式。
start
是一个整数,指定子串的开始位置。
length
是一个整数,指定子串的长度(要返回的字符数或字节数)。
SELECT x = SUBSTRING('abcdef', 2, 3)
下面是结果集:
x ---------- bcd

 
(4)
LEFT ( character_expression , integer_expression )
最左边的 5 个字符。
RIGHT ( character_expression , integer_expression )
参数
最右边的五个字符
 
(5)

UPPER ( character_expression )

返回将小写字符数据转换为大写的字符表达式

LOWER ( character_expression )

将大写字符数据转换为小写字符数据后返回字符表达式。

(6)

REVERSE ( character_expression )

返回字符表达式的反转。

(7)

CAST:
CAST ( expression AS data_type )
将某种数据类型的表达式显式转换为另一种数据类型
declare @a int
cast(@a as varchar(10))--从而连接动态语句
(8)
ISNUMERIC ( expression )

当输入表达式得数为一个有效的整数、浮点数、 moneydecimal 类型,那么 ISNUMERIC 返回 1;否则返回 0。返回值为 1 确保可以将 expression 转换为上述数字类型中的一种。
注意判断后返回的是0和1,与它具有相同用法的就是ISDATE ( expression )
如:case when ISNUMERIC(字段)=1 then '数字' else '字符' end

事例18:
首页随机显示一条:
select top 1 * from qynews where stype='4' order by newid()
 
  事例19:

 sum(1)=count(1)=count(*)  

sum(1)有一条记录就会加1,最后得到的就是记录总数,如果分组就可以得到每组的记录数

order by 1

按照查出的第一列排序

order by 2
按照查出的第二列排序

 


-按某一字段分组取最大(小)值所在行的数据


--(爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 2007-10-23于浙江杭州)


/*


数据如下:


name val memo


a 2 a2(a的第二个值)


a 1 a1--a的第一个值


a 3 a3:a的第三个值


b 1 b1--b的第一个值


b 3 b3:b的第三个值


b 2 b2b2b2b2


b 4 b4b4


b 5 b5b5b5b5b5


*/


--创建表并插入数据:


create table tb(name varchar(10),val int,memo varchar(20))


insert into tb values('a', 2, 'a2(a的第二个值)')


insert into tb values('a', 1, 'a1--a的第一个值')


insert into tb values('a', 3, 'a3:a的第三个值')


insert into tb values('b', 1, 'b1--b的第一个值')


insert into tb values('b', 3, 'b3:b的第三个值')


insert into tb values('b', 2, 'b2b2b2b2')


insert into tb values('b', 4, 'b4b4')


insert into tb values('b', 5, 'b5b5b5b5b5')


go





--一、按name分组取val最大的值所在行的数据。


--方法1:


select a.* from tb a where val = (select max(val) from tb where name = a.name) order by a.name


--方法2:


select a.* from tb a where not exists(select 1 from tb where name = a.name and val > a.val)


--方法3:


select a.* from tb a,(select name,max(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name


--方法4:


select a.* from tb a inner join (select name , max(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name


--方法5


select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name


/*


name val memo


---------- ----------- --------------------


a 3 a3:a的第三个值


b 5 b5b5b5b5b5


*/





--二、按name分组取val最小的值所在行的数据。


--方法1:


select a.* from tb a where val = (select min(val) from tb where name = a.name) order by a.name


--方法2:


select a.* from tb a where not exists(select 1 from tb where name = a.name and val < a.val)


--方法3:


select a.* from tb a,(select name,min(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name


--方法4:


select a.* from tb a inner join (select name , min(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name


--方法5


select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val < a.val) order by a.name


/*


name val memo


---------- ----------- --------------------


a 1 a1--a的第一个值


b 1 b1--b的第一个值


*/





--三、按name分组取第一次出现的行所在的数据。


select a.* from tb a where val = (select top 1 val from tb where name = a.name) order by a.name


/*


name val memo


---------- ----------- --------------------


a 2 a2(a的第二个值)


b 1 b1--b的第一个值


*/





--四、按name分组随机取一条数据。


select a.* from tb a where val = (select top 1 val from tb where name = a.name order by newid()) order by a.name


/*


name val memo


---------- ----------- --------------------


a 1 a1--a的第一个值


b 5 b5b5b5b5b5


*/





--五、按name分组取最小的两个(N个)val


select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val < a.val ) order by a.name,a.val


select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val) order by a.name,a.val


select a.* from tb a where exists (select count(*) from tb where name = a.name and val < a.val having Count(*) < 2) order by a.name,a.val


/*


name val memo


---------- ----------- --------------------


a 1 a1--a的第一个值


a 2 a2(a的第二个值)


b 1 b1--b的第一个值


b 2 b2b2b2b2


*/





--六、按name分组取最大的两个(N个)val


select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val


select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val desc) order by a.name,a.val


select a.* from tb a where exists (select count(*) from tb where name = a.name and val > a.val having Count(*) < 2) order by a.name , a.val


/*


name val memo


---------- ----------- --------------------


a 2 a2(a的第二个值)


a 3 a3:a的第三个值


b 4 b4b4


b 5 b5b5b5b5b5


*/


--七,如果整行数据有重复,所有的列都相同。


/*


数据如下:


name val memo


a 2 a2(a的第二个值)


a 1 a1--a的第一个值


a 1 a1--a的第一个值


a 3 a3:a的第三个值


a 3 a3:a的第三个值


b 1 b1--b的第一个值


b 3 b3:b的第三个值


b 2 b2b2b2b2


b 4 b4b4


b 5 b5b5b5b5b5


*/


--在sql server 2000中只能用一个临时表来解决,生成一个自增列,先对val取最大或最小,然后再通过自增列来取数据。


--创建表并插入数据:


create table tb(name varchar(10),val int,memo varchar(20))


insert into tb values('a', 2, 'a2(a的第二个值)')


insert into tb values('a', 1, 'a1--a的第一个值')


insert into tb values('a', 1, 'a1--a的第一个值')


insert into tb values('a', 3, 'a3:a的第三个值')


insert into tb values('a', 3, 'a3:a的第三个值')


insert into tb values('b', 1, 'b1--b的第一个值')


insert into tb values('b', 3, 'b3:b的第三个值')


insert into tb values('b', 2, 'b2b2b2b2')


insert into tb values('b', 4, 'b4b4')


insert into tb values('b', 5, 'b5b5b5b5b5')


go





select * , px = identity(int,1,1) into tmp from tb





select m.name,m.val,m.memo from


(


select t.* from tmp t where val = (select min(val) from tmp where name = t.name)


) m where px = (select min(px) from


(


select t.* from tmp t where val = (select min(val) from tmp where name = t.name)


) n where n.name = m.name)





drop table tb,tmp





/*


name val memo


---------- ----------- --------------------


a 1 a1--a的第一个值


b 1 b1--b的第一个值





(2 行受影响)


*/


--在sql server 2005中可以使用row_number函数,不需要使用临时表。


--创建表并插入数据:


create table tb(name varchar(10),val int,memo varchar(20))


insert into tb values('a', 2, 'a2(a的第二个值)')


insert into tb values('a', 1, 'a1--a的第一个值')


insert into tb values('a', 1, 'a1--a的第一个值')


insert into tb values('a', 3, 'a3:a的第三个值')


insert into tb values('a', 3, 'a3:a的第三个值')


insert into tb values('b', 1, 'b1--b的第一个值')


insert into tb values('b', 3, 'b3:b的第三个值')


insert into tb values('b', 2, 'b2b2b2b2')


insert into tb values('b', 4, 'b4b4')


insert into tb values('b', 5, 'b5b5b5b5b5')


go





select m.name,m.val,m.memo from


(


select * , px = row_number() over(order by name , val) from tb


) m where px = (select min(px) from


(


select * , px = row_number() over(order by name , val) from tb


) n where n.name = m.name)





drop table tb





/*


name val memo


---------- ----------- --------------------


a 1 a1--a的第一个值


b 1 b1--b的第一个值





(2 行受影响)


*/




取第三条记录

create   table   stu(name   varchar(10),age   int)

insert   into   stu

select   'jac ',20   union   all

select   'tom ',30   union   all

select   'irs ',25



--cost   42.51%

select   top   1   *   from   stu   where   name   not   in     (select   top   2   name   from   stu)  

/*

name               age                  

----------   -----------  

irs                 25

*/



--cost   47.71%



select   *   from   stu   where   not   exists(select   1   from  

(select   top   2   name   from   stu)     t   where   name=stu.name)

/*

name               age                  

----------   -----------  

irs                 25

*/



drop   table   stu



--------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值