精妙SQL

来源:互联网 发布:搜客淘宝客怎么样 编辑:程序博客网 时间:2024/05/01 13:05
格式  
 
说明:复制表(只复制结构,源表名:a  新表名:b)  
SQL:  select  *  into  b  from  a  where  1<>1  
---------------------------------------------------------------  
 
说明:拷贝表(拷贝数据,源表名:a  目标表名:b)  
 
insert  into  b(a,  b,  c)  select  d,e,f  from  b;  
---------------------------------------------------------------  
 
说明:合并数据(表名1:a  表名2:b)  
 
select  a,b,c  from  a  union  select  d,e,f  from  b;  
 
---------------------------------------------------------------  
 
说明:子查询(表名1:a  表名2:b)  
select  a,b,c  from  a  where  a  IN  (select  d  from  b  )  
 
或者:  
 
select  a,b,c  from  a  where  a  IN  (1,2,3)  
---------------------------------------------------------------  
 
俺来贴个让俺对sql茅塞顿开的例子  
 
说明:显示文章、提交人和最后回复时间  
sql:select  a.title,a.username,b.adddate  from  table  a,(select  max(adddate)  adddate  from  table  where  table.title=a.title)  b  
---------------------------------------------------------------  
 
自连接取出荣于数据  
 
把所有姓名相同的只取出一个  
select  a.name  from  table_name  a  where  a.id  in    
 (select  b.id  from  table_name  b  where  a.id<>b.id)  
同理删除荣誉数据  
delete  from  table_name    where  table_name.id  in    
 (select  b.id  from  table_name  b  where  table_name.id<>b.id)  
 
---------------------------------------------------------------  
 
select  isNull(A.name,B.name),isnull(a.code,B.code)  from  table1  A  
full  out  join  table2  B  on  
A.id  =  B.id  
---------------------------------------------------------------  
 
功能:  
type      vender  pcs  
电脑      A                1  
电脑      A                1  
光盘      B                2  
光盘      A                2  
手机      B                3  
手机      C                3  
 
select  type,sum(case  vender  when  'A'  then  pcs  else  0  end),sum(case  vender  when  'C'  then  pcs  else  0  end),sum(case  vender  when  'B'  then  pcs  else  0  end)  FROM  tablename  group  by  type  
---------------------------------------------------------------  
 
to  annkie(活着便精彩)    
看看上面的语句是否解决了问题?  
纠正一下,应该是  
SELECT  DISTINCT  kzx4dm,(SELECT  COUNT(jylsfsdm)  FROM  tablename  WHERE  kzx4dm=TA.kzx4dm)  AS  bys_count,(SELECT  COUNT(jylsfsdm)  FROM  tablename  WHERE  kzx4dm=TA.kzx4dm  AND  jylsfsdm=10)  AS  yjs_count,yjs_count/bys_count  AS  jy_ratio  
FROM  tablename  AS  TA  
 
---------------------------------------------------------------  
 
select  *  from  日程安排  where  datediff('minute',f开始时间,getdate())>5  
日程安排提前五分钟提醒。  
---------------------------------------------------------------  
 
CREATE  OR  REPLACE  PROCEDURE  DUMP_TO_WEB_TCLHD_SP_OBJ  
AS  
BEGIN  
CALC_PIA_PRICE  ;  
DELETE  FROM  TCLHD_SP_OBJ  ;  
INSERT  INTO  TCLHD_SP_OBJ  (NAME,CODE,ID,PRICE,TYPE,FIELDS)  (  
SELECT  c.DESCRIPTION,C.SEGMENT1,a.INVENTORY_ITEM_ID,  nvl(c.ATTRIBUTE14,'0'),0,nvl(c.ATTRIBUTE13,0)  
from  mtl_item_categories  a  ,  mtl_categories  b  ,  mtl_system_items  c        
where  a.CATEGORY_ID  =  b.CATEGORY_ID  and  b.SEGMENT1='原材料'    
and  a.INVENTORY_ITEM_ID  =  c.INVENTORY_ITEM_ID  AND  A.ORGANIZATION_ID  =  21          
and  c.ORGANIZATION_ID  =  21  and  c.inventory_item_status_code  =  'Active'  );  
 
COMMIT  ;  
END  ;  
 
---------------------------------------------------------------  
 
从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源)  
 
SELECT  a.userper,  a.tel,  a.standfee,  TO_CHAR(a.telfeedate,  'yyyy')  AS  telyear,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '01',  a.factration))  AS  JAN,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '02',  a.factration))  AS  FRI,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '03',  a.factration))  AS  MAR,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '04',  a.factration))  AS  APR,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '05',  a.factration))  AS  MAY,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '06',  a.factration))  AS  JUE,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '07',  a.factration))  AS  JUL,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '08',  a.factration))  AS  AGU,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '09',  a.factration))  AS  SEP,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '10',  a.factration))  AS  OCT,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '11',  a.factration))  AS  NOV,  
           SUM(decode(TO_CHAR(a.telfeedate,  'mm'),  '12',  a.factration))  AS  DEC  
FROM  (SELECT  a.userper,  a.tel,  a.standfee,  b.telfeedate,  b.factration  
               FROM  TELFEESTAND  a,  TELFEE  b  
               WHERE  a.tel  =  b.telfax)  a  
GROUP  BY  a.userper,  a.tel,  a.standfee,  TO_CHAR(a.telfeedate,  'yyyy')  
---------------------------------------------------------------  
 
有意思,我也来一个,解决跳号的问题:  
select  min(bh)+1  from  Table1  where  bh+1  not  in(select  bh  from  Table1)  
---------------------------------------------------------------  
 
个人认为,偶写了这么久的SQL,只说语法很无聊,语句的涵义与灵活的组合很重要,下面这个是写的一个药品管理的存储过程的一句,很经典:  
           UPDATE  药房库存  SET  库存数量=库存数量-B.用量  FROM  [药房库存]  A  ,  
           (  Select  sum(用量)  as  用量,药品价码  FROM  处方项    
                           WHERE  处方号=@RecipeNo  AND  处方序号=@RecipeXNo    
                       GROUP  BY  药品价码  
           )  B    WHERE  A.药品价码=B.药品价码  AND  A.库房名称=@DepotName  
 
这是一个参照B表将A表中库存一一修改,而B表中存在一个求和,A表也与B表关联,同时要满足A表条件。  
---------------------------------------------------------------  
 
应聘做了一个小程序,在多人中表现最好,高兴,散分100!!是关于sql查询显示的  
题目大概是SQL          表1:班级/老师        表2学生/班级                表三数学/学生            表4语文/学生  
查询显示结果大概是这样:  
 
班级1    老师1  
学生1      数学    语文  
学生2      数学    语文  
班级2    老师1  
学生1      数学    语文  
学生2      数学    语文  
 
不及格:  
学生1      班级1  老师1    数学    语文    
学生1      班级1  老师1    数学    语文  
还有录入学生和成绩的界面  
 
用到了多表之间的inner  join    on  语句,而且我显示的很漂亮,靠,做了一下午,我好想抽烟啊,当时:)  
看我的,四表联查问题:  
select  *  from  a  left  inner  join  b  on  a.a=b.b  right  inner  join  c  on  a.a=c.c    inner  join  d  on  a.a=d.d  where  .....  
 
---------------------------------------------------------------  
 
需求:  
得到表中最小的未使用的ID号。  
 
例:  
table  Name:Handle  
HandleID  
--------  
1  
2  
5  
6  
7  
--5  Records  
执行结果须为3  
 
解决:  
SELECT  (CASE  WHEN  EXISTS(SELECT  *  FROM  Handle  b  WHERE  b.HandleID  =  1)  THEN  MIN(HandleID)  +  1  ELSE  1  END)  as  HandleID  
 FROM    Handle  
 WHERE  NOT  HandleID  IN  (SELECT  a.HandleID  -  1  FROM  Handle  a)  
 
---------------------------------------------------------------  
 
两台SQL服务器上的一个数据表同步!  
 
drop  procedure  dbSync  
GO  
 
/*          数据同步                                            */  
CREATE  PROCEDURE  dbSync    
             @sTabelName    varchar(255),        --要同步的表名  
             @sKeyField      varchar(255),        --关键字段  
             @sServer          varchar(255),        --服务器名称或IP  
             @sUserName      varchar(255),        --登录到服务器的用户名,一般为sa  
             @sPassWord      varchar(32)            --用户登录到服务器的密码    
AS  
 
 
     /*删除临时表*/  
   if  exists  (select  *  from  dbo.sysobjects  where  id  =  object_id(N'tempTbl')  and  OBJECTPROPERTY(id,  N'IsUserTable')  =  1)  
   drop  table  tempTbl  
     
                                 
   declare  @sql  VARCHAR(2000)    
 
   /*把表@sTabelName[远程]的数据拷贝到临时表*/  
       
   set  @sql='select  *  into  tempTbl  from  '  
   set  @sql=@sql  +  '  OPENDATASOURCE(  '  
   set  @sql=@sql  +  '''SQLOLEDB.1'','  
   set  @sql=@sql  +  '''Persist  Security  Info=True;User  ID='  +  @sUserName  
   set  @sql=@sql  +  ';Password='  +  @sPassWord  
   set  @sql=@sql  +  ';Initial  Catalog=toys;Data  Source='  +  @sServer  
   set  @sql=@sql  +  ''').toys.dbo.'+@sTabelName  
 
   EXEC(@sql)      
 
     
   /*  把@sTabelName[本地]中的@sTabelName[远程]表中没有的数据插入到临时表中*/  
 
   set  @sql='insert  into  tempTbl  select  *  from  '+@sTabelName+'  where  ['+@sKeyField+']  not  in  (select  ['+@sKeyField+']  from  tempTbl)'  
 
   EXEC(@sql)  
     
 
   /*清空表@sTabelName[本地]*/  
   set  @sql='truncate  table  '+@sTabelName  
 
   EXEC(@sql)  
 
     
   --取得列名  
   declare  @MySql  VARCHAR(2000)  
   set  @MySql=''  
   declare  @title  varchar(20)  
 
   DECLARE  titles_cursor  CURSOR  FOR    
 
   SELECT  name  from  syscolumns  where  id=object_id(@sTabelName)  
 
   OPEN  titles_cursor  
 
   FETCH  NEXT  FROM  titles_cursor  INTO  @title  
 
   WHILE  @@FETCH_STATUS  =  0  
   BEGIN  
       if  @title<>'id'    
       begin  
           if  @MySql  =  ''  
               set  @MySq