zoukankan      html  css  js  c++  java
  • MySQL脚本

    NAVICAT快捷键:

    ctrl + r:运行当前查询页面的所有sql语句
    ctrl + shift + r:运行所选择的sql语句
    ctrl + q:打开一个新的查询页面
    ctrl + /:注释
    ctrl + shift + ctrl:取消注释
    ctrl + l:删除当前行
    ctrl + d:复制当前行
    ctrl + f:查找当前页面的内容

    注意事项:

    1、枚举:tinyint 类型;
    2、数据库表的默认编码格式:utf8mb4;
    3、单个字段不用特意写明编码格式,好像默认utf8;
    4、创建时间修改时间用 now()  或者  什么当前时间

     DDL修改(关键字COLUMN可要可不要,只不过有了这个更加好理解):

    ALTER TABLE test ADD COLUMN dd VARCHAR(20) DEFAULT NULL COMMENT 'cao dd' AFTER `haha`;
    ALTER TABLE test DROP COLUMN dd;
    ALTER TABLE test MODIFY COLUMN cc CHAR(30) DEFAULT NULL COMMENT 'cc';

    SHOW:

    show create table `user`; -- 查看建表语句
    SHOW VARIABLES LIKE '%datadir%'; -- 查看本地MySQL数据的保存路径,我的点人电脑放在:C:ProgramDataMySQLMySQL Server 8.0Data
    
    SHOW FULL COLUMNS FROM tableshaha;  -- 超级强大,一定要记住,查看表注释的另外一种方法,比information schema强大多了
    SHOW COLUMNS FROM tableshaha;  -- 在我看来,和上面的区别就是,上面显示的有注释,这个没有注释,这个是简短版的
    SHOW TABLE STATUS LIKE '%org%'  -- 对于InnoDB类型的表,这样来显示信息,终于找到了一种方法来快速模糊查找表了
    SHOW INDEX FROM emp -- 查询索引的具体信息
    
    SHOW CREATE VIEW test_view -- 查询视图信息,目前对于我来说没有什么用
    SHOW STATUS LIKE 'Com_%';  -- 查询执行增删改查的情况,目前对于我来说没有什么用
    SHOW STATUS LIKE 'Handler_read%'; -- 查看索引的使用情况,目前对于我来说没有什么用
    
    SHOW DATABASES; -- 查看当前连接下有多少数据库
    USE test; -- 选择某一个数据库
    SHOW tables; -- 查看表

     information_schema(常用的主要还是第一条):

    SELECT COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,COLUMN_DEFAULT,COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_NAME = 'tm_esim_special_pay'; -- 这个经常用,因为可以快速查看注释嘛
    SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE DATA_TYPE = 'enum'; -- 这个在一次工作当中发挥了重要的作用,因为那个时候我要把整个数据库表里面的枚举类型变成varchar类型

    其它:

    INSERT INTO t2 (SELECT * FROM t1) -- 这样插入都行很厉害,相当于将数据复制多一份,t2的表结构必须与t1的一模一样,不推荐这种方式
    INSERT INTO t3 (col1,col2,col3) (SELECT col4,col5,col6 FROM t4)  -- 这样插入,但是后面的一定要与字段个数一致
    
    SELECT deptno,count(*) FROM emp GROUP BY deptno WITH ROLLUP -- 既要统计各部门人数,又要统计总人数,这个函数不能与orderby同时使用
    SELECT * FROM emp ORDER BY RAND() -- 将行打乱,随机行
    SELECT * FROM emp PROCEDURE ANALYSE(); -- 这个sql语句分析值与字段之间的关系真的很强大 
    SELECT VERSION(); -- 查询数据库工具版本
    
    -- 定期检查表,优化表
    ANALYZE TABLE emp;
    CHECK TABLE emp;
    OPTIMIZE TABLE emp;

     处理时间:

    SELECT CURDATE();  -- 当前日期
    SELECT CURTIME();  -- 当前时间
    SELECT NOW(); -- 当前日期时间
    SELECT SYSDATE(); -- 当前日期时间
    
    -- NOW()与SYSDATE()的区别:
    -- NOW():这条sql语句执行时立刻得到当前时间值;
    -- SYSDATE():执行到当前语句之后,执行到该函数时的当前时间值;
    -- 也正因为有这个区别,我们一般在执行语句的时候,都是用NOW(),因为SYSDATE获取当时实时的时间,这有可能导致主库和从库是执行的返回值是不一样的,导致主从数据不一致。
    SELECT NOW(),SLEEP(3),NOW(); -- 2018-08-16 19:03:51,0,2018-08-16 19:03:51
    SELECT SYSDATE(),SLEEP(3),SYSDATE();-- 2018-08-16 19:03:54,0,2018-08-16 19:03:57
    
    SELECT DATE_FORMAT(CURDATE(),'%w'); -- 获取今天是星期几,返回阿拉伯数字,这个准确
    SELECT DAYOFWEEK(CURDATE()); -- 返回今天是星期几(1=星期天,2=星期一,……7=星期六,ODBC标准),这个不准确
    SELECT WEEKDAY(CURDATE());   -- 返回今天是星期几(0=星期一,1=星期二,……6= 星期天),这个不准确
    SELECT DAYOFMONTH(CURDATE()); -- 返回今天是当月中的第几日(在1到31范围内)   
    SELECT DAYOFYEAR(CURDATE()); -- 返回今天是当年中的第几日(在1到366范围内) 
    SELECT MONTH(CURDATE());     -- 11 返回当前月份
    SELECT DAYNAME(CURDATE());   -- Friday 按英文名返回今天是星期几
    SELECT MONTHNAME(CURDATE()); -- November 按英文名返回当月是几月份
    SELECT QUARTER(CURDATE());   -- 返回现在的第几季度
    SELECT WEEK(CURDATE());      -- 46 这个不准确
    SELECT YEAR(CURDATE()); -- 2019
    SELECT YEARWEEK(CURDATE()); -- 201946  这个不准确
    SELECT WEEKOFYEAR(CURDATE());-- 47 这个准确
    
    SELECT DATEDIFF(CURDATE(),'1989-10-23') -- 两个日期之间的天数差
    SELECT TIMESTAMPDIFF(SECOND,'2019-11-11',SYSDATE()); -- 两个日期相差多少时间,秒或者分之类的
    -- 第三个参数不仅可以是DAY,还可以是MONTH, YEAR,代表加减一个月,一年
    SELECT DATE_SUB('2018-05-01',INTERVAL 1 DAY); -- 定义日期减一天
    SELECT DATE_SUB(CURDATE(),INTERVAL 1 DAY); -- 当前日期减一天
    SELECT DATE_SUB('2018-05-01',INTERVAL -1 DAY); -- 如果为负数的话,负负得正
    SELECT DATE_ADD('2018-05-01',INTERVAL 1 MONTH); -- 输出2018-06-01 
    SELECT DATE_ADD(CURDATE(),INTERVAL 9 HOUR); -- 查询当天早上9点
    
    -- 注意,这三个是一样的
    SELECT SUBDATE(CURDATE(),INTERVAL 7 DAY);
    SELECT SUBDATE(CURDATE(),7);
    SELECT DATE_SUB(CURDATE(),INTERVAL 7 DAY);
    
    SELECT STR_TO_DATE(NOW(),'%Y-%m-%d %H:%i:%s') -- 字符串转日期:2017-12-29 23:59:14
    SELECT DATE_FORMAT(NOW(),'%Y-%m-%d %T')  -- 日期转字符串:%T 二十四小时制:2017-12-29 23:59:46
    SELECT DATE_FORMAT(NOW(),'%Y-%m-%d %r')  -- 日期转字符串:%r 十二小时制:2017-12-30 12:00:00 AM
    SELECT DATE('2017-12-29 11:58:54 PM') -- 返回日期或日期时间表达式的日期部分:2017-12-29
    SELECT DATE_FORMAT(CURDATE(),'%Y-%m-%d 00:00:00');-- 获取当天零点零分零秒;其实如果字段类型是date类型的话,就默认当天零点零分了
    SELECT DATE_FORMAT(CURDATE(),'%Y-%m-%d 23:59:59');-- 。。。。。。
    
    SELECT SUBDATE(CURDATE(),(WEEKDAY(CURDATE()) + 7)); -- 上个星期一的日期
    SELECT SUBDATE(CURDATE(),(WEEKDAY(CURDATE()) + 1)); -- 上个星期天的日期
    SELECT SUBDATE(CURDATE(),WEEKDAY(CURDATE())); -- 这个星期一的日期
    SELECT SUBDATE(CURDATE(),(WEEKDAY(CURDATE()) - 6)); -- 这个星期天的日期
    
    SELECT DATE_SUB(SUBDATE(CURDATE(),(DAYOFMONTH(CURDATE())-1)),INTERVAL 1 MONTH); -- 上个月第一天
    SELECT SUBDATE(CURDATE(),DAYOFMONTH(CURDATE())); -- 上个月最后一天

     处理字符串:

    SELECT CONCAT('aa','bb','cc')   -- 将aa,bb,cc连接成字符串
    SELECT CONCAT_WS('-','aa','bb','cc') -- 将aa,bb,cc连接成字符串,并用'-'隔开
    SELECT INSERT('郭晓锋你好',2,3,'郭辉')  -- 将被替换字符串'郭晓锋',从第2个开始(晓),截取3个长度(晓锋你),替换成'郭晓辉'
    SELECT LOWER('AAABc')  -- 变小写  
    SELECT LCASE('AAABc')  -- 变小写  
    SELECT UPPER('AAABc')  -- 变大写  
    SELECT UCASE('AAABc')  -- 变大写  
    SELECT LEFT('12345',3)  -- 123
    SELECT RIGHT('12345',3)  -- 345
    SELECT LENGTH('12345')   -- 5
    SELECT POSITION('a' IN '345ababc') -- 前面那个字符串在后面出现的位置
    SELECT REVERSE('123456') -- 颠倒字符串
    SELECT TRIM('asd ')  -- 去掉空格,LTRIM(),RTRIM()
    SELECT SUBSTRING('12345678',2,3)  -- 被截取字符串从第二位开始,截取三位长度,也就是变成了'234';其实,SUBSTR也可以
    SELECT SUBSTRING('12345678',2)    -- 如果没有写截取的长度,则截取全部,变成了'2345678';其实,SUBSTR也可以
    SELECT REPLACE('2015-01','-','')  -- 变成了 '201501'
    SELECT REPEAT('str',4) -- 返回从字符串str x 位置起y 个字符长度的字串,结果为:strstrstrstr
    select lpad('2008',20,'beijing'),rpad('beijing',20,'2008');  -- beijingbeijingbe2008,beijing2008200820082
    select replace('beijing2010','2010','2008'); -- 用2008替换2010
    SELECT SUBSTRING_INDEX('blog.jb51.net','.',1); -- blog
    SELECT SUBSTRING_INDEX('blog.jb51.net','.',2); -- blog.jb51
    SELECT SUBSTRING_INDEX('blog.jb51.net','.',-1);-- net
    SELECT SUBSTRING_INDEX('blog.jb51.net','.',-2);-- jb51.net

     UNION UNION ALL 的主要区别:

    UNION ALL 是把结果集直接合并在一起,而UNION 是将UNION ALL 后的结果进行一次DISTINCT,去除重复记录后的结果。(注意,两个select语句返回的字段名一定要是一样的)

     处理数字:

    select ABS(-0.8) ,ABS(0.8); -- 返回绝对值
    SELECT CEIL(1.8),CEIL(-1.8) -- 返回大于1.8的最大整数,里面要是小数啊
    SELECT FLOOR(1.8),FLOOR(-1.8) -- 返回小于1.8的最大整数,里面要是小数啊
    SELECT MOD(5,3) -- 取模
    SELECT RAND() -- 0到1之间随机值
    SELECT CEIL(100 * RAND()) -- 0到100之间随机整数
    SELECT ROUND(23.1284,2) -- 四舍五入2位小数值
    SELECT TRUNCATE(23.1284,2) -- 截断 ,剩两位小数
    
    -- 关于数字拼接的特殊性
    SELECT '1' + '-'; -- 1
    SELECT '1' + '2'; -- 3
    SELECT '1' + '-' + '2'; -- 3
    SELECT CONCAT('1','2'); -- 12
    SELECT CONCAT('1','-','2'); -- 12

     删除重复值(只保留一个)

    -- 不能:
    DELETE FROM testa WHERE ID NOT IN (
        (SELECT MAX(ID) AS ID FROM testa GROUP BY `name`)
    )
    -- mysql中You can't specify target table for update in FROM clause错误的意思是说,不能先select出同一表中的某些值,再update这个表(在同一语句中)。注意,这个问题只出现于mysql,mssql和oracle不会出现此问题。
    -- 这样(用临时表):
    DELETE FROM testa WHERE ID NOT IN (
        SELECT a.ID FROM (
            (SELECT MAX(ID) AS ID FROM testa GROUP BY `name`)
        )a
    )

     关于IF以及NULL

    SELECT 
        (CASE WHEN t.empno = 7844  -- 这样写的话,可以大于号小于号等等
                    THEN (SELECT empno FROM emp WHERE emp_id = '11')  
            ELSE (SELECT empno FROM emp WHERE emp_id = '12') 
       END)
    FROM
        (SELECT empno FROM emp WHERE emp_id = '00' )t
    
    -- -------------------------------------------------
    
    SELECT 
        (CASE t.empno WHEN 7844  -- 这样写的话,相当于 t.empno = 7844
                                    THEN (SELECT empno FROM emp WHERE emp_id = '11')  
                                    ELSE (SELECT empno FROM emp WHERE emp_id = '12') 
       END)
    FROM
        (SELECT empno FROM emp WHERE emp_id = '00' )t
    
    -- -------------------------------------------------
    
    SELECT IF(t.empno = 7844,
                        (SELECT empno FROM emp WHERE emp_id = '11'),
                        (SELECT empno FROM emp WHERE emp_id = '12') 
                      )
    FROM
        (SELECT empno FROM emp WHERE emp_id = '00' )t
    
    -- --------------------------------------------------------
    
    SELECT ISNULL(NULL);  -- 如果是空值的话就为1(true),如果不是空值的话就为0(false)
    SELECT IFNULL(1,2);  -- 如果1不为空值的话,就返回1,如果1为空值的话,就返回2
    SELECT NULLIF(1,1) -- 如果两个值相等的话,就返回null,否则返回第一个数字
    
    -- 判断是否存在该记录,直接取得总条数就可以了啊,哈哈,这个疑问之前困扰了我一天,所以干事情一定要多思考啊
    -- 是否存在着该条记录,如果存在着该记录,则干某事,否则干某事
    SELECT IF(t.count = 0, (SELECT empno AS count FROM emp WHERE emp_id = '11'), (SELECT empno AS count FROM emp WHERE emp_id = '12') ) FROM (SELECT COUNT(*) AS count FROM emp WHERE emp_id = '005')t

     timestamp 以及 datetime 类型:

    1、如果需要经常插入或者更新日期为当前系统时间,则通常使用TIMESTAMP 来表示;
    2、TIMESTAMP 值返回后显示为“YYYY-MM-DD HH:MM:SS”格式的字符串,显示宽度固定为19 个字符;
    3、timestamp 那里的默认值可以写上 CURRENT_TMIESTAMP 来表示默认当前时间,其实这个是挺好用的;
    4、TIMESTAMP的取值范围为19700101080001到2038年的某一天,因此它不适合存放比较久远的日期(当插入的值超出取值范围时,MySQL认为该值溢出,使用“0000-00-00 00:00:00”进行填补。),而DATETIME是从1000-01-01 00:00:00到9999-12-31 23:59:59,范围更大;
    5、TIMESTAMP 主要存放跟时区有关的啊,时区,是时区啊,TIMESTAMP的插入和查询都受当地时区的影响,更能反应出实际的日期。而DATETIME则只能反应出插入时当地的时区,其他时区的人查看数据必然会有误差

     更新一个数据表里面的字段值为另外一个:

    -- 之前是这样写的,用子查询,不过这样不好
    UPDATE tm_esim_manual_account ma SET work_place = 
     (SELECT workplace_base_name FROM tm_esim_workplace_base wp WHERE wp.workplace_base_code = ma.work_place)
    
    -- 用连接查询这样会更好,也看得更明白
    UPDATE tm_esim_manual_account ma INNER JOIN tm_city_code cc ON ma.work_place = cc.city_name SET ma.pay_city= cc.city_id

    级联删除(级联之后,只删除其中一个表啊,注意别名):

    DELETE tp FROM test_person tp INNER JOIN cao_test ct ON tp.id = ct.id WHERE ct.haha = '222';

     替换字段里面的某一个值里面特定的字符串成另外的:

    UPDATE `tm_esim_insurance_combine_maintenance` SET insurance_combine = REPLACE(insurance_combine,'',')')

     SUBSTRING_INDEX,GROUP_CONCAT,ORDER BY,GROUP BY 的综合使用(GROUP BY之后的里面的GROUP_CONCAT,用ORDER BY字段排序,然后通过SUBSTRING_INDEX截取里面的相关字段,秒

    SELECT
        SUBSTRING_INDEX(GROUP_CONCAT(t.id ORDER BY t.stats DESC, t.modifier_time DESC),',',1) AS id,
        t.socurity_accum_account,
        SUBSTRING_INDEX(GROUP_CONCAT(t.company_socur_accumAcc ORDER BY t.stats DESC,t.modifier_time DESC),',',1) AS company_socur_accumAcc
    FROM tm_esim_sociala_mainte t 
    WHERE t.effective_date <= CURDATE()
    GROUP BY t.socurity_accum_account

     案例:自定义排序,例如,在emp表中,根据:MANAGER,ANALYST,SALESMAN这几个字段来升序排列:

    SELECT * FROM emp ORDER BY (CASE job WHEN 'MANAGER' THEN '0' WHEN 'ANALYST' THEN '1' WHEN 'SALESMAN' THEN '2' ELSE 3 END);

     求交叉区间,即是说:输入的时间区间同数据库的时间区间不能有交叉,有交叉,则返回数据。这个在工作中的一个项目应用十分强,开始不知道这个,如果开始知道这个的话,就不用走那么多弯路了;

    -- 数据库的开始时间大于输入来的结束时间,或者数据库的结束时间小于输入来的开始时间,这两种情况下,则无交叉,求反集,即是有交叉的了;这里的应用主要是NOT NOT NOT 啊
    SELECT * FROM country WHERE NOT (begin_date > '2018-05-25' OR end_date < '2018-05-01')

    更新在今天之前的某些数据(如果这个语句早知道,那样的话在工作中就少些很多垃圾代码了)(其实工作中的很多代码,都可以用连接查询代替子查询的了):

    -- 后来的一开始是这样写的:
    UPDATE table_01
    SET status_a = 1
    WHERE valid_date < CURDATE() 
    AND status_a = 0 
    AND insurance_combine IN (
        SELECT t.insurance_combine FROM (
                 SELECT icm.insurance_combine FROM table_01 icm WHERE icm.status_a = 0 AND icm.valid_date = date_format(NOW(),'%y-%m-%d') GROUP BY id
        )t
    );
    -- 但是用子查询的效率比不上连接查询的效率高:
    UPDATE table_01 t1
    INNER JOIN (SELECT icm.insurance_combine FROM table_01 icm WHERE icm.status_a = 0 AND icm.valid_date = date_format(NOW(),'%y-%m-%d') GROUP BY id)t2
            ON t1.insurance_combine = t2.insurance_combine
    SET t1.status_a = 1
    WHERE t1.valid_date < CURDATE() 
    AND t1.status_a = 0 

     发现新大陆(批量更新):

    UPDATE cao_dept SET dept = (CASE id WHEN '11' THEN '1111' WHEN '22' THEN '2222' WHEN '33' THEN '3333' WHEN '44' THEN '4444' ELSE '' END) WHERE id IN ('11','22','33','44')

     END!

    SELECT h.value AS item_value, h.itemid
    FROM history AS h
    RIGHT JOIN (SELECT itemid, MAX(clock) AS clock FROM history GROUP BY itemid) AS m
    ON h.itemid=m.itemid AND h.clock=m.clock
  • 相关阅读:
    re模块
    Docker的使用
    flask中请求勾子
    flask中的蓝图实现模块化的应用
    HTTP中常见的各种状态码详解及解决方案
    git快速入门
    2st week blog 1
    web个人介绍
    CentOS7下shell脚本实现限定范围类的随机数
    CentOS7下shell脚本大小比较
  • 原文地址:https://www.cnblogs.com/ericguoxiaofeng/p/8098508.html
Copyright © 2011-2022 走看看