zoukankan      html  css  js  c++  java
  • SQL语句

    1、将查询结果导入另一个表中

    (1)、查询A表部分字段导入B表

    insert into B表(字段1,字段2,字段3)

    select 字段1,字段2,字段3 from A表

    where ......

    B表中的每个字段要和 从A表中读取的字段一致。

    B表中除了上边显示的字段外,还可以有其它的字段,但是要保证其它字段的属性为null,否则会报错。

    (2)、A表数据全部导入B表(A、B表的所有字段完全相同,字段名可省掉)

    insert into B表

    select * from A表

    where......

    (3)、字段名不同,但字段属性一致,可以使用别名。(注意:别名的三种不同写法)

    insert into B表(字段1,字段2,字段3)

    select 字段a as 字段1,字段2 = 字段b,字段c 字段3

    from A表

    where.....

    (4)、以上的三种情况都是先创建好所要插入数据的B表,也可以在插入数据时自动的创建B表

    select * into B表 from A表

    2、分别查出每个小组中人数最多的三个地区:

    方法一:

    select *
    from Persons t1
    where
    (
    select count(*)
    from Persons t2
    where t1.小组=t2.小组
    and t2.人数>=t1.人数
    ) <=3

    方法二:(不理解)

    set statistics profile on
    select 小组,地区,人数
    from
    (select row_number()
    over(partition by 小组
    order by 人数 desc) as Number,* from Persons
    )T
    where T.Number<=3

    3、从A表 中取出第31到第40条记录:  

    (1)、select top 40* from A表 except  select top 30* from 

    (2)、select top 10 * from A表 where ID not in(select top 30 ID from A表)

    4、

    insert into AreaDev
    select c.Code area ,(select isnull(a.num,0)) num from CXFLDM c
    left join areadev a on c.code=a.area 
    where c.code>100000 and c.code<9000000

    5、

    //查询出所有数据库中的所有表的列表
    select * from sysobjects

    //查询出所有的列名
    select * from syscolumns

    //查询出数据库中“subject”列名的所有表
    select a.name from sysobjects a,syscolumns b where a.id = b.id and b.name = 'subject'

    6、根据某个值 查询出在数据库中出现过该值的某个表名和所在的列表名  存储过程如下:

    CREATE PROCEDURE [dbo].[SP_FindValueInDB]
    (
        
    @value VARCHAR(1024)
    )        
    AS
    BEGIN
        
    -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
    SET NOCOUNT ON;
    DECLARE @sql VARCHAR(1024
    DECLARE @table VARCHAR(64
    DECLARE @column VARCHAR(64

    CREATE TABLE #t ( 
        tablename 
    VARCHAR(64), 
        columnname 
    VARCHAR(64


    DECLARE TABLES CURSOR 
    FOR 

        
    SELECT o.name, c.name 
        
    FROM syscolumns c 
        
    INNER JOIN sysobjects o ON c.id = o.id 
        
    WHERE o.type = 'U' AND c.xtype IN (167175231239
        
    ORDER BY o.name, c.name 

    OPEN TABLES 

    FETCH NEXT FROM TABLES 
    INTO @table@column 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
        
    SET @sql = 'IF EXISTS(SELECT NULL FROM [' + @table + '' 
        
    SET @sql = @sql + 'WHERE RTRIM(LTRIM([' + @column + '])) LIKE ''%' + @value + '%''' 
        
    SET @sql = @sql + 'INSERT INTO #t VALUES (''' + @table + '''''' 
        
    SET @sql = @sql + @column + ''')' 

        
    EXEC(@sql

        
    FETCH NEXT FROM TABLES 
        
    INTO @table@column 
    END 

    CLOSE TABLES 
    DEALLOCATE TABLES 

    SELECT * 
    FROM #t 

    DROP TABLE #t 


    End

    EXEC [SP_FindValueInDB]   '要查询某个表中的值'

    百分比的表示方法:

    cast(cast(分子*1.0*100/分母 as decimal(10,2)) as varchar(50)) +'%'

    --获取每个月的连续日期字符串

    select timesection=convert(varchar(10),dateadd(day,number,'2013-9-1'),112)
    from master.dbo.spt_values
    where type='P' and dateadd(day,number,'2013-9-1') <= '2013-9-30'

    根据日期统计该月份每天的数据记录 日期格式“yyyy/(M)M/(d)d“

    Create proc P_GZLDTimeAndCountByMonth
    @sDate varchar(10)
    AS
    DECLARE @sql NVARCHAR(3000)
    SELECT @sql='
    select s1.sDate,ISNULL(s2.Area_One,0) as Area_One,ISNULL(s2.Area_Two,0) as Area_Two,ISNULL(s2.Area_Three,0) as Area_Three
    from
    (
    select convert(varchar(100),s.s_date,112) as sDate
    from(
    select DATEADD(dd,number,'''+@sDate+''') as s_date
    from master..spt_values
    where type = ''P'' and DATEADD(dd,number,'''+@sDate+''') < DATEADD(mm,1,'''+@sDate+''')
    )s)as s1
    left join(
    select sdate, count(case when sex=''保养一区'' then 1 end)Area_One ,
    count(case when sex=''保养二区'' then 1 end) Area_Two,
    count(case when sex=''保养三区'' then 1 end) Area_Three
    from CRM_CASE
    group by sdate 
    )s2
    on s1.sDate=s2.sDate

    '
    EXEC (@sql)
    GO

    exec P_GZLDTimeAndCountByMonth '2013/1/1'

    获取某月中 所有天数的记录

    CREATE proc P_GZLDTimeAndCountByMonth
    @sDate1  DATETIME,--当月的第一天
    @sDate2 DATETIME--下月的第一天
    AS

    CREATE TABLE #LDTemp_Table(s_Date varchar(100),sTime varchar(8),ACC_PLAN varchar(20),AREA varchar(50))

    --- 声明一个游标
    DECLARE  my_Cursor  CURSOR scroll FOR
    --获取指定日期  第一天 7点后 和第二个月 第一天7点之前的记录
    select Convert(datetime,sdate) as sdate,stime,Acc_plan,sex
    from CRM_CASE
    where (
    (sDate=Convert(varchar(8), @sDate1,112) and sTime>='070000')
    or (sDate=Convert(varchar(8),@sDate2,112) and sTime<'070000')
    or(sDate> Convert(varchar(8),@sDate1,112) and sDate<  Convert(varchar(8),@sDate2,112)
    )) and Acc_plan='0'
    group by sdate,stime,Acc_Plan,sex

    --打开游标
    OPEN  my_Cursor

    DECLARE @s_Date datetime
    DECLARE @sTime varchar(6)
    DECLARE @ACC_PLAN varchar(20)
    DECLARE @AREA varchar(50)

    FETCH next FROM my_Cursor into @s_Date,@sTime,@ACC_PLAN,@AREA

    WHILE @@FETCH_STATUS=0

    BEGIN
    --如果在07:00:00以后的记录则插入日期为当天,07:00:00之前的记录则插入日期为前一天
    IF(@sTime>='070000')
     INSERT INTO #LDTemp_Table values(@s_Date,@sTime,@ACC_PLAN,@AREA)
    ELSE
     INSERT INTO #LDTemp_Table values(DATEADD(DD,-1,@s_Date),@sTime,@ACC_PLAN,@AREA)
    FETCH NEXT FROM my_Cursor  into @s_Date,@sTime,@ACC_PLAN,@AREA
     
    END

    --关闭游标 释放游标
    CLOSE my_Cursor
    DEALLOCATE  my_Cursor

    --select * from #LDTemp_Table
    ---联合查询 列出当月每天的记录数
    select substring(Convert(varchar(20),s1.sDate,112),7,2)+'号' as sDate,ISNULL(s2.Area_One,0) as Area_One,ISNULL(s2.Area_Two,0) as Area_Two,ISNULL(s2.Area_Three,0) as Area_Three
    from
    (
    select s.s_date as sDate
    from(
    select DATEADD(dd,number,@sDate1) as s_date
    from master..spt_values
    where type = 'P' and DATEADD(dd,number,@sDate1) < DATEADD(mm,1,@sDate1)
    )s)as s1
    left join(
    select s_date,count(case when Area='保养一区' then 1 end)Area_One ,
    count(case when area='保养二区' then 1 end) Area_Two,
    count(case when area='保养三区' then 1 end) Area_Three
    from #LDTemp_Table
    group by s_date
    )s2
    on s1.sDate=s2.s_Date

    --删除临时表
    DROP TABLE #LDTemp_Table
    GO

    CREATE Proc P_GetRepairLDCount
    @beginDate varchar(8),
    @endDate varchar(8),
    @Area varchar(50)
    As
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    --该存储过程是动态的 可随这保养区中维修人员的编号而变化 (注意:站点字段可为空, 保养区的合计报修数量>= 各站点的报修数量总和)
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    if exists (select * from dbo.sysobjects where id=object_id(N'[dbo].[Table_New]') and OBJECTPROPERTY(id,N'IsUserTable') = 1)
    --print 'The UserTable exists'
    drop table Table_New
    ----获取需要的数据列表 (因为“-”在语法上讲不可以作为列名,此处替换为“_”)
    select Replace(station,'-','_')as 站名,Manager as 站长,c_Count as 报修数 into Table_RepairLDCount from(
     select distinct(station)as Station,manager as Manager,ISNULL(c.c_Count,0) as c_Count
     from rl_Area r
     left join
     (
      select sex,job,count(*) as c_Count from CRM_CASE
      where sex=''+@Area+'' and ((sDate=''+@beginDate+'' and sTime>'070000') or (sDate =''+@endDate+'' and sTime<'070000') or (sDate >= ''+@beginDate+'' and sDate< @endDate )) and ACC_PLAN='0'
      group by sex,job
    ) c
    on r.station=c.job where r.Area=''+@Area+''
    group by r.station,r.manager,c.c_Count
    ) t
    ----------计算出该保养区中的所有报修数,并插入到数据表中---------
    DECLARE @Sum varchar(30)
    select @Sum=count(*) from CRM_CASE where sex=''+@Area+'' and ((sDate=''+@beginDate+'' and sTime>'070000') or (sDate =''+@endDate+'' and sTime<'070000') or (sDate >= ''+@beginDate+'' and sDate< @endDate ))  and ACC_PLAN='0'
    --exec('select '+@Sum+'=count(*) from CRM_CASE')
    --print @Sum

    insert into Table_RepairLDCount values('杭州区','合计',@Sum)

    ----执行表旋转操作

    --生成中间数据表
    declare @s varchar(8000)
    set @s = 'create table Table_New (站名 varchar(20)'
    select @s = @s + ',' + 站名 + ' varchar(10)' from Table_RepairLDCount  order by 站名 asc
    set @s = @s + ')'
    exec(@s)
    --print @s

    --借助中间表实现行列转换
    declare @name varchar(20)
     
    declare t_cursor cursor for
    select name from syscolumns
    where id=object_id('Table_RepairLDCount') and colid > 1 order by colid asc
     
    --打开游标
    open t_cursor
    fetch next from t_cursor into @name
     
    while @@fetch_status = 0
    begin
        exec('select ' + @name + ' as t into Tabel_RepairTemp from Table_RepairLDCount  order by 站名 asc')
        set @s='insert into Table_New select ''' + @name + ''''
        select @s = @s + ',''' + rtrim(t) + '''' from Tabel_RepairTemp
        exec(@s)
        exec('drop table Tabel_RepairTemp')
        fetch next from t_cursor into @name
    end
    ---关闭游标
    close t_cursor
    deallocate t_cursor

    --查看行列互换处理结果
    --select * from Table_RepairLDCount
    select * from Table_New

    --删除临时表
    drop table Table_RepairLDCount
    drop table Table_New
    GO

     动态行转列

    declare @sql varchar(8000)
    set @sql = 'select s_Date as ' + 's_Date'
    select @sql = @sql + ' , sum(case Area when ''' + station + ''' then 1 else 0 end) [' + station + ']'
    from (select distinct station from RL_Area where area=@sex) as a
    set @sql = @sql + ' from #NewTable group by s_Date'
    exec(@sql)

    游标使用语法:

    --声明游标:
    DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
         [ FORWARD_ONLY | SCROLL ]
         [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
         [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
         [ TYPE_WARNING ]
         FOR select_statement
         [ FOR UPDATE [ OF column_name [ ,...n ] ] ]
    [;]

    --local 表示为局部游标
    --global 表示为全局游标


    --forward_only 和 scroll 两种
    --forward_only 意味着游标只能从数据集开始向数据集结束的方向读取,fetch next是唯一的选项
    --scroll支持游标在定义的数据集中任何方向,或任何位置移动

    --声明游标并给游标赋值
    declare test_Cursor1 cursor scroll for
    select * from role

    open test_Cursor1

    --跳转到第一行
    fetch first from test_Cursor1

    --跳转到最后一行
    fetch last from test_Cursor1

    --跳转到下一行
    fetch next from test_Cursor1

    --跳转到上一行
    fetch prior from test_Cursor1

    --直接跳转到某行
    fetch absolute 3 from test_Cursor1

    --相对于当前 跳几行 负值表示:向上,正值表示:向下
    fetch relative -1 from test_Cursor1

    --声明并负值
    declare test_Cursor2 cursor for
    select * from role

    open test_Cursor2

    fetch next from test_Cursor2

    --关闭游标
    Close test_Cursor1
    Close test_Cursor2


    --声明游标
    deallocate test_Cursor1

    deallocate test_Cursor2

    --static keyset dynamic 和 fast_forward
    --static:当游标被建立时,将会创建for 后面的select语句所包含的的数据集的副本存入tempdb数据库中,任何对于底层表内数据的更改不会影响
    --到游标的内容。

    --dynamic:和static相反,当底层数据库更改时,游标的内容也随之得到反映,在下一次fetch中,数据内容会随之改变。

    --keyset可以理解为介于static和dynamic的之中方案。将游标所在的结果集的唯一能确定每一行的主键存入tempdb,当结果集中任何行改变或者删除时,
    --@@fetch_status会为-2,keyset无法探测新加入的数据。
    )
    --fast_forward可以理解成forward_only的优化版本,forward_only执行的是静态计划,而fast_forward是根据情况进行选择采用动态计划还是静态计划,大多数情况下
    --fast_forward要比forward_only性能略好。


    --游标尽可能不使用(使用游标会比使用面向集合的方法慢2-3倍。如果有可能,尽量使用while,子查询,临时表,函数,表变量等代替游标。)
    --使用过游标后一定要关闭和释放。
    --尽量不要在大数据上定义游标
    --尽量不适用insensitive,static和keyset参数定义游标
    --如果可以,尽量使用fast_forward关键字定义游标
    --如果只对数据进行读取,当读取时只用到fetch next选项,则最好使用forward_only参数


    select 'insert into depworker(areadepid,workerid,remark) values('+convert(varchar(20),areadepid)+','+convert(varchar(20),workerid)+','''+remark+''')' from depworker

    //查询该数据库中的表的变更时间
    ---------------------------------------------------------------------------------------------------------

    SELECT SO.Name--表名
    ,ISNULL(EP.VALUE,'-') Description --描述
    ,CONVERT(varchar, SO.refdate, 120) as ModifiedTime --最后修改时间
    FROM SYSCOLUMNS SC INNER JOIN SYSOBJECTS SO ON SC.ID = SO.ID AND SO.XTYPE = 'U' AND SO.NAME <> 'SYSDIAGRAMS'
    LEFT JOIN SYS.EXTENDED_PROPERTIES EP ON SC.ID = EP.MAJOR_ID AND EP.MINOR_ID = 0
    WHERE (CASE WHEN SC.COLORDER = 1 THEN SO.NAME ELSE '' END) <> ''
    ORDER BY ModifiedTime DESC

    //获取表的信息
    exec sp_MShelpcolumns tb_Oil_Push
    --------------------------------------------------------------------------------------------------


    /*
    ----根据字段获取该字段所在的存储过程
    ----------------------------------------------------------------------------------------------------
    SELECT obj.Name 存储过程名, sc.TEXT 存储过程内容
    FROM syscomments sc
    INNER JOIN sysobjects obj ON sc.Id = obj.ID
    WHERE sc.TEXT LIKE '%' + 'newid' + '%'
    AND TYPE = 'P'
    GO
    */


    --查看某个字段所在表
    -------------------------------------------------------------------------------------------------
    select 'select * from '+[name] from sysobjects where [id] in (select [id] from syscolumns where [name]='字段名')

    Convert 和Cast 转换
    convert(decimal(16,2) ,12.5)
    或cast(12.5 as decimal(16,2))

    //查询该数据库中的表的变更时间

    SELECT SO.Name--表名
    ,ISNULL(EP.VALUE,'-') Description --描述
    ,CONVERT(varchar, SO.refdate, 120) as ModifiedTime --最后修改时间
    FROM SYSCOLUMNS SC INNER JOIN SYSOBJECTS SO ON SC.ID = SO.ID AND SO.XTYPE = 'U' AND SO.NAME <> 'SYSDIAGRAMS'
    LEFT JOIN SYS.EXTENDED_PROPERTIES EP ON SC.ID = EP.MAJOR_ID AND EP.MINOR_ID = 0
    WHERE (CASE WHEN SC.COLORDER = 1 THEN SO.NAME ELSE '' END) <> ''
    ORDER BY ModifiedTime DESC

    //获取表的信息
    exec sp_MShelpcolumns 表名

    获取每个分组的第一条数据 

    select a,b,c,createtime from
    (select *,rn=ROW_NUMBER()over (PARTITION by a,b order by createtime desc) from tbName)k where k.rn=1

  • 相关阅读:
    Python 命令详解
    redhat 6 / centos 6 搭建Django环境
    Linux rsync 命令详解
    Python 文件处理
    [网络流24题]最长不下降子序列问题
    [网络流24题]圆桌问题
    BZOJ 4675(点分治)
    LOJ 2183 / SDOI2015 序列统计 (DP+矩阵快速幂)
    BZOJ 3931 (网络流+最短路)
    [网络流24题]魔术球问题
  • 原文地址:https://www.cnblogs.com/Shang0109/p/2571206.html
Copyright © 2011-2022 走看看