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

    获取GUID: SELECT NEWID()
    说明:复制表(只复制结构,源表名: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;
    把所有姓名相同的只取出一个
    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 a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

    随机取出10条数据
    select top 10 * from tablename order by newid()

    Microsoft SQL Server是如何加密口令的?未公开的加密函数? 
            
    如果对MSSQL的用户信息有兴趣的,可能会发现master.dbo.sysxlogins里面存放着用户的口令,可是呢,password字段如果不是null就是一堆看不懂的binary,这个口令是怎么加密的呢?


    其实只要仔细看看master.dbo.sp_addlogin就知道了,MSSQL的sp都可以看到代码,真是不错。
    让我们来看看它是怎么做的,注意这一行select 
    @passwd = pwdencrypt(@passwd),这个时后@passwd就被加密了,让我们也来试一下
    DECLARE @ClearPWD varchar(255
    DECLARE @EncryptedPWD varbinary(255)
    SELECT @ClearPWD = 'test'
    SELECT @EncryptedPWD = CONVERT(varbinary(255), pwdencrypt(@ClearPWD))
    SELECT @EncryptedPWD
    看上去不错,确实被加密了,可是我怎么还原呢? 

    呵呵,这就没戏了,口令加密都是单向的,用加密后的密文来比较就可以了。
    继续看看其它用户相关的sp,可以发现master.dbo.sp_password里面有口令比较的内容。
    pwdcompare(
    @old, password, (CASE WHEN xstatus&2048 = 2048 THEN 1 ELSE 0 END))
    不用去理会xstatus,这是一个状态掩码,一般我们用的时候就直接用0就可以了
    DECLARE @ClearPWD varchar(255
    DECLARE @EncryptedPWD varbinary(255)
    SELECT @ClearPWD = 'test'
    SELECT @EncryptedPWD = CONVERT(varbinary(255), pwdencrypt(@ClearPWD))
    SELECT pwdcompare(@ClearPWD@EncryptedPWD0)
    SELECT pwdcompare('ErrorPassword'@EncryptedPWD0)
    这样我们就可以使用这两个函数来加密自己的密码了,怎么样,还不错吧?


    1.如果 T 表还有一字段 F0 数据类型为自动增量整型(唯一,不会重复),
      而且 T 表中含有除 F0 字段外,请删除其它字段完全相同的重复多余的脏记录数据:
    delete from t  where f0 in(select max(f0) from t group by f1,f2,f3,f4,f5,f6,f7 having count(f0)>1)

    上面这个sql有问题
    正确的如下

    DELETE Legal_Dispute_Lawyer WHERE Lawyer_Record_No IN(SELECT Lawyer_Record_No FROM Legal_Dispute_Lawyer LDL WHERE Lawyer_Record_No(SELECT TOP 1 Lawyer_Record_No FROM Legal_Dispute_Lawyer WHERE LD=LDL.LD AND Name=LDL.Name AND Email=LDL.Email AND Phone_No=LDL.Phone_No AND Fax_No=LDL.Fax_No))

    消除Legal_Dispute_Lawyer 表中除Lawyer_Record_No(自增字段)外其余数据完全相同的记录.
    表结构如下
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Legal_Dispute_Lawyer]'and OBJECTPROPERTY(id, N'IsUserTable'= 1)
    drop table [dbo].[Legal_Dispute_Lawyer]
    GO

    CREATE TABLE [dbo].[Legal_Dispute_Lawyer] (
     
    [Lawyer_Record_No] [int] IDENTITY (11NOT NULL ,
     
    [LD] [int] NOT NULL ,
     
    [Name] [int] NOT NULL ,
     
    [Phone_No] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,
     
    [Fax_No] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,
     
    [Email] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL 
    ON [PRIMARY]
    GO


    分页语句
    select top 100 * from 表名 where id not in (select top page_no*100 * from 表名)
    page_no是程序中的变量

    从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源)

    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')

    个人认为,偶写了这么久的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表条件。

    两台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 @MySql = @MySql + @title
          
    else
            
    set @MySql = @MySql + ',' + @title
        
    end
        
    FETCH NEXT FROM titles_cursor INTO @title
      
    END

      
    CLOSE titles_cursor

      
    DEALLOCATE titles_cursor
      
    --取列名结束


      
    /*把临时表的内容插入到表@sTabelName[本地]*/
      
    set @sql='insert into '+@sTabelName+' select '+@MySql+' from tempTbl'

      
    EXEC(@sql


      
    /*删除临时表*/
      
    if exists (select * from dbo.sysobjects where id = object_id(N'tempTbl'and OBJECTPROPERTY(id, N'IsUserTable'= 1)
      
    drop table tempTbl

    GO

    select a,b,c from a where a IN (select d from b )
    这是一个可以优化的sql语句,给a表中的a和b表中的d使用索引,然后改为
    select a,b,c from a where exists (select * from b where b.d=a.a)

    总结说一点:
    1、要合理使用索引
    索引是数据库一个重要的构成部分,很多人都会忽略它,其实索引的根本目的就是
    为了提高查询效率。
    使用原则如下: 
    在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则
    由优化器自动生成索引。 

    在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引。 

    在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要
    建立索引。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就
    无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度
    。 
    如果待排序的列有多个,可以在这些列上建立复合索引(compound 
    index)。 

    在写sql语句时就必须注意有些写法是会使得数据库无法使用索引的,比如IS 
    NULL
    IS NOT NULLIN ,NOT IN 等。。。

    2.避免或简化排序 
    应当简化或避免对大型表进行重复的排序。当能够利用索引自动以适当的次序产生
    输出时,优化器就避免了排序的步骤。以下是一些影响因素: 
    ●索引中不包括一个或几个待排序的列; 
    group by或order by子句中列的次序与索引的次序不一样; 
    ●排序的列来自不同的表。 
    为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表(尽管有时可
    能影响表的规范化,但相对于效率的提高是值得的)。如果排序不可避免,那么应
    当试图简化它,如缩小排序的列的范围等。 
    3.消除对大型表行数据的顺序存取 
    在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。比如采用顺序存
    取策略,一个嵌套3层的查询,如果每层都查询1000行,那么这个查询就要查询10
    亿行数据。避免这种情况的主要方法就是对连接的列进行索引。例如,两个表:学
    生表(学号、姓名、年龄……)和选课表(学号、课程号、成绩)。如果两个表要
    做连接,就要在“学号”这个连接字段上建立索引。 
    还可以使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的
    where子句强迫优化器使用顺序存取。下面的查询将强迫对orders表执行顺序操作
    : 
    SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001OR 
    order_num
    =1008 
    虽然在customer_num和order_num上建有索引,但是在上面的语句中优化器还是使
    用顺序存取路径扫描整个表。因为这个语句要检索的是分离的行的集合,所以应该
    改为如下语句: 
    SELECT * FROM orders WHERE customer_num=104 AND order_num>1001 
    UNION 
    SELECT * FROM orders WHERE order_num=1008 
    这样就能利用索引路径处理查询。 
    4.避免相关子查询 
    一个列的标签同时在主查询和where子句中的查询中出现,那么很可能当主查询中
    的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此
    应当尽量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的
    行。 
    5.避免困难的正规表达式 
    MATCHES和LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗
    费时间。例如:
    SELECT * FROM customer WHERE zipcode LIKE “98_ _ _” 
    即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如
    果把语句改为SELECT * 
    FROM customer WHERE zipcode >98000”,在执行查询
    时就会利用索引来查询,显然会大大提高速度。 
    另外,还要避免非开始的子串。例如语句:
    SELECT * FROM customer WHERE 
    zipcode
    [2,3] >80”,在where子句中采用了非开始子串,因而这个语句也不会
    使用索引。 
    6.使用临时表加速查询 
    把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排序
    操作,而且在其他方面还能简化优化器的工作。例如: 
    SELECT cust.name,rcvbles.balance,……other columns 
    FROM cust,rcvbles 
    WHERE cust.customer_id = rcvlbes.customer_id 
    AND rcvblls.balance>0 
    AND cust.postcode>98000” 
    ORDER BY cust.name 
    如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个
    临时文件中,并按客户的名字进行排序: 
    SELECT cust.name,rcvbles.balance,……other columns 
    FROM cust,rcvbles 
    WHERE cust.customer_id = rcvlbes.customer_id 
    AND rcvblls.balance>0 
    ORDER BY cust.name 
    INTO TEMP cust_with_balance 
    然后以下面的方式在临时表中查询: 
    SELECT * FROM cust_with_balance 
    WHERE postcode>98000” 
    临时表中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘
    I
    /O,所以查询工作量可以得到大幅减少。 
    注意:临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下,注意
    不要丢失数据。 
    7.用排序来取代非顺序存取 
    非顺序磁盘存取是最慢的操作,表现在磁盘存取臂的来回移动。SQL语句隐藏了这
    一情况,使得我们在写应用程序时很容易写出要求存取大量非顺序页的查询。 
    有些时候,用数据库的排序能力来替代非顺序的存取能改进查询。 

  • 相关阅读:
    在ASP.NET中使用FusionCharts图表
    IE 输入baidu就死掉
    以WebServices方式上传图片
    GUID System.Guid .
    记录一个静态类的静态属性
    [转]通用分页存储过程
    如何解决“呈现控件时出错”的问题
    C#中调用SQL存储过程(带输入输出参数的例子)
    Rose实例:构造银行业务模型[转]
    Mylove net 我们手里的金钱只是保持自由的一种工具!卢梭
  • 原文地址:https://www.cnblogs.com/msn/p/567951.html
Copyright © 2011-2022 走看看