zoukankan      html  css  js  c++  java
  • 常用SQL笔记

    记录下SQL笔记,久了没用忘掉了,咳,真TMD郁闷

    分组后WHERE用having

    SELECT FAge,COUNT(*) AS CountOfThisAge FROM T_Employee GROUP BY FAge HAVING COUNT (*) IN (1,3)

    Group by 按需求取得指定数据

    SELECT data.* from table as data right join (select max(id) as id from table group by gbfield) as temp on temp.id=data.id

    GROUP BY 的时候可以获取用函数获得指定字段的值,通过以上方法可以获取指定结果集 但group by 的字段要做索引,否则效率很低

    防止重复数据的产生
    SELECT DISTINCT FDepartment FROM T_Employee;

    字段间计算

    SELECT 125+521 as staticnm,FNumber,FName,FAge * FSalary FROM T_Employee;

    字符串处理

    SELECT FName, LENGTH(FName) AS namelength FROM T_Employee WHERE FName IS NOT NULL

    SELECT FName, SUBSTRING(FName,2,3) FROM T_Employee WHERE FName IS NOT NULL

    SELECT CONCAT('年龄:',FAge) FROM T_Employee

    结果集联合(需要遵守:一是每个结果集必须有相同的列数;二是每个结果集的列必须类型相容。)

    SELECT FNumber,FName,FAge FROM T_Employee UNION SELECT FIdCardNumber,FName,FAge FROM T_TempEmployee

    默认情况下,UNION运算符合并了两个查询结果集,需要在联合结果集中返回所有的记录而不管它们是否唯一,则需要在 UNION运算符后使用ALL操作符,比如下面的SQL语句:
    SELECT FName,FAge FROM T_Employee UNION ALL SELECT FName,FAge FROM T_TempEmployee

    使用UNION的时候各列的顺序最好相同,不然有很多意想不到的结果

    MYSQL中使用DATEDIFF()函数用于计算两个日期之间的差额

    SELECT FRegDay,FBirthDay, DATEDIFF(FRegDay, FBirthDay) , DATEDIFF(FBirthDay ,FRegDay)FROM T_Person

    CASE函数

    SELECT FName,

    (CASE FName

    WHEN 'Tom' THEN 'GoodBoy'
    WHEN 'Lily' THEN 'GoodGirl'
    WHEN 'Sam' THEN 'BadBoy'
    WHEN 'Kerry' THEN 'BadGirl'
    ELSE 'Normal'
    END) as isgood

    FROM T_Person

    但字段值为NULL的时候case NULL 无效

    该使用 

    SELECT FName,

    if (isnull(isgood),'good','bad') as isgood

    FROM T_Person

    MYSQL不支持如下,当DB2等数据库支持

    一次定义多次使用

    WITH person_tom AS
    (
    SELECT * FROM T_Person
    WHERE FName='TOM'
    )
    SELECT * FROM T_Person
    WHERE FAge=person_tom.FAge
    OR FSalary=person_tom.FSalary

    ANY关键词的意思是“对于在子查询返回的列中的任一数值,如果比较结果为TRUE的话,则返回TRUE”。
    有一真为真
    SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);
    词语IN是=ANY的别名。因此,这两个语句是一样的:
    SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2);
    SELECT s1 FROM t1 WHERE s1 IN    (SELECT s1 FROM t2);
    词语ALL必须接在一个比较操作符的后面。ALL的意思是“对于子查询返回的列中的所有值,如果比较结果为TRUE,则返回TRUE。”例如:
    多个比较
    SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2);
    SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);
    如果在表t2的一个行中,column1=1并且column2=2,则查询结果均为TRUE。

    EXISTS和NOT EXISTS
    EXISTS (有结果为真 无结果为假) 下个相反
    如果一个子查询返回任何的行,则EXISTS subquery为FALSE 
    子查询结果为单个时候可以直接等于~(小心使用~)
    SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
    正常表达式
    select * from xxx where  aa regexp 'xxx';
    select * from xxx where aa regexp "";

    join 将两个表合到一个表进行查询 字段合并 合并条件以on为准
    select * from test1 join test2 on test1.a=test2.d
    select * from t1 join  (t2, t3, t4) on (t1.id=t2.id and t2.id=t3.id and t3.id=t1.id ) #复杂查询
    记得跟ON 语句
    left join  以左表为基准
    right join 以右表为基准
    join 两个表都因同时存在记录为基准

    链表删除
    delete t1 from test1 as t1 join test2 ad t2 on t1.a=t2.a where t2.c='3'

    链表更新

    update test1 ad t1 join test2 as t2 on t1.a=t2.a set t1.b='100' where t2.c='4';

    链表同步
    update test1 as t1 join test2  as t2 set t1.b=t2.c where t1.a=t2.a

    查询插入

    insert into b (level,name) select level,name from a order by level desc limit 20 ; 

    连表分页

    select * from (select * from test1 union select * from test2) as temp limit 0,100;

    返回一个不同值的数目。
    mysql> select COUNT(DISTINCT results) from student;

    group by 中字段中使用函数是对汇总子表的操作
    汇总并返回平均数
    mysql> select student_name, AVG(test_score)
               from student
               GROUP BY student_name;

    链表的时候尽量不要GROUP BY ,是非常缓慢的...

    INSTR(str,substr)
    返回子串substr在字符串str中的第一个出现的位置。这与有2个参数形式的LOCATE()相同,除了参数被颠倒。
    mysql> select INSTR('foobarbar', 'bar');
            -> 4
    mysql> select INSTR('xbar', 'foobar');
            -> 0

    LPAD(str,len,padstr)
    返回字符串str,左面用字符串padstr填补直到str是len个字符长。
    mysql> select LPAD('hi',4,'??');
            -> '??hi'
     
    LEFT(str,len)
    返回字符串str的最左面len个字符。
    mysql> select LEFT('foobarbar', 5);
            -> 'fooba'

    该函数是多字节可靠的。

    RIGHT(str,len)
    返回字符串str的最右面len个字符。
    mysql> select RIGHT('foobarbar', 4);
            -> 'rbar'

    该函数是多字节可靠的。


    REPEAT(str,count)
    返回由重复countTimes次的字符串str组成的一个字符串。如果count <= 0,返回一个空字符串。如果str或count是NULL,返回NULL。
    mysql> select REPEAT('MySQL', 3);
            -> 'MySQLMySQLMySQL'
    LOWER(str)
    返回字符串str,根据当前字符集映射(缺省是ISO-8859-1 Latin1)把所有的字符改变成小写。该函数对多字节是可靠的。
    mysql> select LCASE('QUADRATICALLY');
            -> 'quadratically'

    查询插入:

    insert into table1 select field21 as field11 ,field22 ad field12 from table2 where file11='test';

    查询结果创建一个列并赋值默认值

    select *,'test' as newfield from test;

     汇总后合并汇总那些行的结果到一行

    SELECT g, group_concat( test1 SEPARATOR "-" ) AS bbb FROM a_test GROUP BY g

    不一定搭配group by 使用

    SELECT g, group_concat( test1 SEPARATOR "-" ) AS bbb FROM a_test

    直接把表里指定字段的数据全链接,默认用,链接

    除非简单查询,GROUP_CONCAT用于复杂查询将是不可行的

    插入更新:ON DUPLICATE KEY UPDATE

    条件更新:(非常有用~)

    update t2
    set b=case
    when a<2 then b+1
    when a>2 then 0
    end

    UNIX时间戳转日期格式

    select FROM_UNIXTIME(1156219870);
     

    连表join注意:join 的时候会连接一个表,组成新表后在连下一个表,如

     SELECT * FROM `a_ta` as ta join a_tc as tc on ta.id=tc.id  join a_tb as tb on ta.id=tb.id

    先a_ta和a_tc组成一个表,在和a_tb组成一个表

    没有on语句的时候 会由每一个记录来组成一个表,所以查出来的结果是两个表记录的卡迪尔积,

    join on结果是两个表同时存在记录的那些记录 但ON不能加判断值.

    如 on ta.id='1' 是不行的...

    where between a and b;//在字段AB之间

    where between 1 and 2;//在1和2之间

    行转列

    //转自:cnblogs.com/kerrycode

    我们首先先通过一个老生常谈的例子,学生成绩表(下面简化了些)来形象了解下行转列 

    代码
    CREATE  TABLE [StudentScores]
    (
        
    [UserName]         NVARCHAR(20),        --学生姓名
        [Subject]          NVARCHAR(30),        --科目
        [Score]            FLOAT,               --成绩
    )

    INSERT INTO [StudentScores] SELECT 'Nick''语文'80

    INSERT INTO [StudentScores] SELECT 'Nick''数学'90

    INSERT INTO [StudentScores] SELECT 'Nick''英语'70

    INSERT INTO [StudentScores] SELECT 'Nick''生物'85

    INSERT INTO [StudentScores] SELECT 'Kent''语文'80

    INSERT INTO [StudentScores] SELECT 'Kent''数学'90

    INSERT INTO [StudentScores] SELECT 'Kent''英语'70

    INSERT INTO [StudentScores] SELECT 'Kent''生物'85

     如果我想知道每位学生的每科成绩,而且每个学生的全部成绩排成一行,这样方便我查看、统计,导出数据

    代码
    SELECT 
          UserName, 
          
    MAX(CASE Subject WHEN '语文' THEN Score ELSE 0 ENDAS '语文',
          
    MAX(CASE Subject WHEN '数学' THEN Score ELSE 0 ENDAS '数学',
          
    MAX(CASE Subject WHEN '英语' THEN Score ELSE 0 ENDAS '英语',
          
    MAX(CASE Subject WHEN '生物' THEN Score ELSE 0 ENDAS '生物'
    FROM dbo.[StudentScores]
    GROUP BY UserName
    解释:增加4列,并根据指定行的情况赋值该列,汇总结果并取得指定列的最大值,没有该记录结果就是0

     按照IN里的顺序取数据

    id in (1,2,3) order by FIELD(id, 1,2,3)

    id in (1,2,3) order by substring_index('1,2,3',id,1);

    //效率都差不多~

    重结果集里获取随机数据

    SELECT * FROM ko_channel ORDER BY rand() LIMIT 2

    分组结果并获取每条分组中的一个记录

    select *, count(distinct name) from table group by name

    SQL获取两个经纬度距离

    6367000*2*ASIN(LEAST(
    1,SQRT(
    POW( SIN( (RADIANS(X(GEOMFROMTEXT('POINT({$point})'))) - RADIANS(X(location))) /2 ), 2)
    +
    COS(
    RADIANS(X(location))
    )
    *COS(
    RADIANS(X(GEOMFROMTEXT('POINT({$point})')))
    )
    *POW( SIN( (RADIANS(Y(GEOMFROMTEXT('POINT({$point})'))) - RADIANS(Y(location))) / 2 ), 2 )
    )
    ))

    存储过程动态调用存储过程

    SET @fn = CONCAT('CALL order_rollback_',buy_type,'(?,?)');
    PREPARE stmt1 FROM @fn;
    SET @a = id_product;
    SET @b = buy_num;
    EXECUTE stmt1 USING @a, @b;
    DEALLOCATE PREPARE stmt1;

    事件

    CREATE EVENT order_pay_rollback ON SCHEDULE AT '2016-11-11 11:11:11' ON COMPLETION NOT PRESERVE ENABLE DO CALL order_pay_rollback(11);

    存储过程

    CREATE PROCEDURE order_pay_rollback(id_order_pay int)
    BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE id_product int;
    DECLARE cur1 CURSOR FOR SELECT
    id_product as id_product
    FROM p  
    WHERE id_order_pay=id_order_pay ;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN cur1;
    read_loop: LOOP
    FETCH cur1 INTO id_product;
    IF done THEN
    LEAVE read_loop;
    END IF;
    CALL order_rollback(id_product);
    END LOOP;
    close cur1;
    END;

  • 相关阅读:
    C语言习题(结构)
    java变量
    大咖分享 | 一文解锁首届云创大会干货——上篇(文末附演讲ppt文件免费下载)
    深入解读Service Mesh的数据面Envoy
    appium封装显示等待Wait类和ExpectedCondition接口
    Jmeter压测Thrift服务接口
    浏览器插件及好用的小工具
    Jmeter入门实例
    BugBash活动分享
    如何作缺陷分析
  • 原文地址:https://www.cnblogs.com/liushannet/p/1805592.html
Copyright © 2011-2022 走看看