zoukankan      html  css  js  c++  java
  • SQL基础-DML

    insert语句

    mysql> insert into students(sid,sname,scardid,saddr,hobby,salary,sdate) values(1000,'lisi','110102','北京市','足 球,羽毛球',10001.00,now());
    
    mysql> create table t1(id int,name varchar(10));
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> alter table t1 add primary key (id);
    Query OK, 0 rows affected (0.05 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> insert into t1 values(1,'tom');
    Query OK, 1 row affected (0.01 sec)

    使语句可重复执行 insert ignore

    mysql> insert into t1 values(1,'jerry');
    ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
    
    mysql> insert ignore into t1 values(1,'jerry');
    Query OK, 0 rows affected, 1 warning (0.00 sec)
    
    mysql> show warnings;
    +---------+------+---------------------------------------+
    | Level   | Code | Message                               |
    +---------+------+---------------------------------------+
    | Warning | 1062 | Duplicate entry '1' for key 'PRIMARY' |
    +---------+------+---------------------------------------+
    1 row in set (0.00 sec)

    插入多条数据语句

    mysql> insert ignore into t1 values(2,'jerry'),(3,'jack');
    Query OK, 2 rows affected (0.00 sec)
    Records: 2  Duplicates: 0  Warnings: 0

    其他插入语句实例

    mysql> insert into t1 set id=4,name='lucy';
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into t1 select * from t2;

    使用replace替换数据

    ## 注意,在没有约束的时候,会新插入数据

    mysql> replace into t1 values(4,'lily');        
    Query OK, 2 rows affected (0.00 sec) 
    
    mysql> select * from t1;
    +----+-------+
    | id | name  |
    +----+-------+
    |  1 | tom   |
    |  2 | jerry |
    |  3 | jack  |
    |  4 | lily  |
    +----+-------+
    4 rows in set (0.00 sec) 
    
    mysql> create table t2 as select * from t1;
    Query OK, 4 rows affected (0.03 sec)
    Records: 4  Duplicates: 0  Warnings: 0
    
    mysql> desc t2;
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id    | int(11)     | NO   |     | NULL    |       |
    | name  | varchar(10) | YES  |     | NULL    |       |
    +-------+-------------+------+-----+---------+-------+
    2 rows in set (0.00 sec)
    
    mysql> select * from t2;
    +----+-------+
    | id | name  |
    +----+-------+
    |  1 | tom   |
    |  2 | jerry |
    |  3 | jack  |
    |  4 | lily  |
    +----+-------+
    4 rows in set (0.01 sec)
    
    mysql> replace into t2 values(4,'lucy');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from t2;
    +----+-------+
    | id | name  |
    +----+-------+
    |  1 | tom   |
    |  2 | jerry |
    |  3 | jack  |
    |  4 | lily  |
    |  4 | lucy  |
    +----+-------+
    5 rows in set (0.00 sec)
    
    mysql> alter table t1 add unique key unq_name(name);
    Query OK, 0 rows affected (0.16 sec)
    Records: 0  Duplicates: 0  Warnings: 0

    update

    update TABLE_NAME SET xxx=xxx where

    注意点: 更新列的个数,where条件最好带索引列,更新索引列的值时,有可能会出现页分片,尽量在业务不繁忙的时候更新索引列。

    当有索引的时候update是顺序修改,在做批量修改的时候可以使用order by

    mysql> select * from t1;
    +----+-------+
    | id | name  |
    +----+-------+
    |  3 | jack  |
    |  2 | jerry |
    |  4 | lily  |
    |  1 | tom   |
    +----+-------+
    4 rows in set (0.00 sec)
     
    mysql> update t1 set id=id+1;
    ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY' 
    
    mysql> update t1 set id=id+1 order by id desc;
    Query OK, 4 rows affected (0.00 sec)
    Rows matched: 4  Changed: 4  Warnings: 0
    
    mysql> select * from t1;
    +----+-------+
    | id | name  |
    +----+-------+
    |  4 | jack  |
    |  3 | jerry |
    |  5 | lily  |
    |  2 | tom   |
    +----+-------+
    4 rows in set (0.00 sec)

    limit 限制改多少行

    mysql> alter table t1 add age int unsigned;
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> update t1 set age=20 where id>2 limit 1;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    mysql> select * from t1;
    +----+-------+------+
    | id | name  | age  |
    +----+-------+------+
    |  2 | tom   | NULL |
    |  3 | jerry |   20 |
    |  4 | jack  |   10 |
    |  5 | lily  |   10 |
    +----+-------+------+
    4 rows in set (0.00 sec)

    delete

    delete from t2 where id=4;
    
    注意点: where 条件,索引

    伪删除(在表中添加状态列state,update时加条件)

    mysql> alter table t2 add column state int not null default 1;
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> desc t2;
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id    | int(11)     | NO   |     | NULL    |       |
    | name  | varchar(10) | YES  |     | NULL    |       |
    | state | int(11)     | NO   |     | 1       |       |
    +-------+-------------+------+-----+---------+-------+
    3 rows in set (0.00 sec) 
    
    mysql> select * from t2;
    +----+-------+-------+
    | id | name  | state |
    +----+-------+-------+
    |  1 | tom   |     1 |
    |  2 | jerry |     1 |
    |  3 | jack  |     1 |
    |  4 | lily  |     1 |
    |  4 | lucy  |     1 |
    +----+-------+-------+
    5 rows in set (0.00 sec) 
    
    mysql> update t2 set state=0 where id >=4;
    Query OK, 2 rows affected (0.01 sec)
    Rows matched: 2  Changed: 2  Warnings: 0 
    
    mysql> select * from t2 where state =1;
    +----+-------+-------+
    | id | name  | state |
    +----+-------+-------+
    |  1 | tom   |     1 |
    |  2 | jerry |     1 |
    |  3 | jack  |     1 |
    +----+-------+-------+
    3 rows in set (0.00 sec)

    select

    select 查询参数(变量)值

    mysql> select @@innodb_flush_log_at_trx_commit;
    +----------------------------------+
    | @@innodb_flush_log_at_trx_commit |
    +----------------------------------+
    |                                1 |
    +----------------------------------+
    1 row in set (0.00 sec) 
    
    mysql> select @@datadir;
    +------------------------+
    | @@datadir              |
    +------------------------+
    | /data/mysql/data_3306/ |
    +------------------------+
    1 row in set (0.00 sec) 
    
    mysql> show variables like '%trx%'G
    *************************** 1. row ***************************
    Variable_name: innodb_api_trx_level
            Value: 0
    *************************** 2. row ***************************
    Variable_name: innodb_flush_log_at_trx_commit
            Value: 1
    2 rows in set (0.00 sec)

    select查询函数

    mysql> select pi()*2*5 from dual;
    +-----------+
    | pi()*2*5  |
    +-----------+
    | 31.415927 |
    +-----------+
    1 row in set (0.00 sec)
    
    mysql> select current_user();
    +----------------+
    | current_user() |
    +----------------+
    | root@localhost |
    +----------------+
    1 row in set (0.00 sec)

    select标准使用

    单表查询

    1、 多子句的执行顺序

    select
    
    from 从哪来
    
    where 过滤条件
    
    group by 分组条件
    
    select_list 列条件
    
    having 后过滤条件
    
    order by 排序条件
    
    limit 分页

     from子句应用

    1. 获取世界上所有城市信息
    
    SELECT * FROM city;
    
    ===>
    
    SELECT id,NAME,coutrycode,District ,population FROM city;

    select应用举例

    1、获取世界上所有城市名和人口数

    SELECT NAME,population FROM city;

     2、where 子句应用

     2.1 等值查询

    2.1.1 查询中国(CHN)所有的城市

    SELECT * FROM city WHERE countrycode='CHN';

    2.1.2 查询中国或美国的所有城市信息

    SELECT * FROM city WHERE countrycode='CHN' OR countrycode='USA' ;
    
    SELECT * FROM city WHERE countrycode IN ('CHN','USA');
    
    SELECT * FROM city WHERE countrycode='CHN'
    
    UNION ALL
    
    SELECT * FROM city WHERE countrycode='USA' ;
    
    SELECT countrycode,CASE countrycode WHEN countrycode = 'CHN' THEN NAME END FROM city;

    2.1.3 UNION和UNION ALL 差别,union 是要去重复的。

    说明: union all 语句在索引合理的时候,比in性能好一些

    如果说,在索引不合理的时候,需要多次查同一表时,性能肯能不如in

     

    例如:以下语句,最好改写为case语句

    SELECT SUM(invalid_count) as invalid_count,
    
    SUM(confirm_count) as
    
    confirm_count,SUM(not_confirm_count) as
    
    not_confirm_count,SUM(total_count) as total_count
    
    FROM (
    
    select count(att.LogID) as invalid_count, 0
    
    as confirm_count,0 as not_confirm_count,0 as
    
    total_count,bp.city_id
    
    FROM builder_project_info as bp
    
    JOIN attendentlog as att ON bp.project_id =
    
    att.CompanyID
    
    WHERE att.CompanyID in (SELECT project_id from builder_project_info WHERE city_id = 407) and att.LogTime like "2019-06%" and att.state = 2
    
    GROUP BY bp.city_id
    
    UNION all (
    
    select 0 as invalid_count, count(att.LogID)
    
    as confirm_count,0 as not_confirm_count,0 as
    
    total_count,bp.city_id
    
    FROM builder_project_info as bp
    
    JOIN attendentlog as att ON bp.project_id =
    
    att.CompanyID
    
    WHERE att.CompanyID in (SELECT project_id from
    
    builder_project_info WHERE city_id = 407) and
    
    att.LogTime like "2019-06%" and att.state = 1
    
    GROUP BY bp.city_id
    
    )
    
    UNION all (
    
    select 0 as invalid_count, 0 as
    
    confirm_count,count(att.LogID) as not_confirm_count,0
    
    as total_count,bp.city_id
    
    FROM builder_project_info as bp
    
    JOIN attendentlog as att ON bp.project_id =
    
    att.CompanyID
    
    WHERE att.CompanyID in (SELECT project_id from
    
    builder_project_info WHERE city_id = 407) and
    
    att.LogTime like "2019-06%" and att.state = 0
    
    GROUP BY bp.city_id
    
    )
    
    UNION all (
    
    select 0 as invalid_count, 0 as confirm_count,0 as
    
    not_confirm_count,count(att.LogID) as
    
    total_count,bp.city_id
    
    FROM builder_project_info as bp
    
    JOIN attendentlog as att ON bp.project_id =
    
    att.CompanyID
    
    WHERE att.CompanyID in (SELECT project_id from
    
    builder_project_info WHERE city_id = 407) and
    
    att.LogTime like "2019-06%"
    
    GROUP BY bp.city_id
    
    )
    
    ) as a
    
    GROUP BY a.city_id

    改写后:

    SELECT
    
    COUNT(CASE WHEN att.state=0 THEN 1 END) AS a,
    
    COUNT(CASE WHEN att.state=1 THEN 1 END) AS b,
    
    COUNT(CASE WHEN att.state=2 THEN 1 END) AS c,
    
    sum(att.LogID)
    
    FROM builder_project_info AS bp
    
    JOIN attendentlog AS att ON bp.project_id =
    
    att.CompanyID
    
    WHERE bp.city_id=407
    
    AND att.LogTime LIKE "2019-06%"
    
    AND att.state IN (0,1,2)
    
    GROUP BY bp.city_id;

    2.1.3  WHERE + LIKE 使用(字符串列)

    --- 查询一下国家的code是CH开头的。

    SELECT * FROM city WHERE countrycode LIKE 'CH%';

    注意不要出现 LIKE '%CH%',不走索引。

     4. where 不等值查询 (> < >= <=,!= <>,not in)

    不等于!=、<>、not in查询不走索引,除非是主键列

    例如:

    mysql> desc select CountryCode,name from city where id>100;

    +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+

    | id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |

    +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+

    |  1 | SIMPLE      | city  | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL | 2094 |   100.00 | Using where |

    +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+

    1 row in set, 1 warning (0.00 sec)

     

    SELECT * FROM city WHERE population<100;

    SELECT * FROM city WHERE countrycode != 'CHN' ;

    SELECT * FROM city WHERE countrycode NOT IN

    ('CHN','USA');

    SELECT * FROM city WHERE Population>=1000000 AND

    Population<=2000000;

    SELECT * FROM city WHERE Population BETWEEN 1000000 AND

    2000000;

     

    -- group by + 聚合函数

    (sum(),avg(),count(),max(),min(),group_concat())

    -- 1. 统计city表中,每个国家的城市个数

    SELECT countrycode,COUNT(id) FROM city GROUP BY countrycode;

    -- 2. 统计一下每个国家的总人口

    SELECT countrycode ,SUM(population)

    FROM city

    GROUP BY countrycode;

    -- 3. 统计一下中国每个省的总人口

    SELECT district ,SUM(population)

    FROM city

    WHERE countrycode='CHN'

    GROUP BY district;

    -- 4. 统计每个国家的城市个数和城市名

    SELECT countrycode,COUNT(id),GROUP_CONCAT(NAME) FROM

    city

    GROUP BY countrycode;

    执行逻辑:

    1. 按照group by条件进行排序

    2. 去重复

    3. 聚合列

     

    sql_mode问题:

    mysql> SELECT countrycode,id FROM city

    -> GROUP BY countrycode;

    ERROR 1055 (42000): Expression #2 of SELECT list is not

    in GROUP BY clause and contains nonaggregated column

    'world.city.ID' which is not functionally dependent on

    columns in GROUP BY clause; this is incompatible with

    sql_mode=only_full_group_by

     

    -- 5.分组聚合group_concat(column_name):将返回的column值按一行显示,避免1对多

     

    -- having 后判断(不走索引)

    -- 1. 统计一下中国每个省的总人口,将总人口超过500w的显示出来

    SELECT district ,SUM(population)

    FROM city

    WHERE countrycode='CHN'

    GROUP BY district

    HAVING SUM(population) >5000000;

     

    --- order by 子句应用(不走索引)

    -- 统计一下中国每个省的总人口,将总人口超过500w的显示出来,总人口

    从大到小排序

    SELECT district ,SUM(population)

    FROM city

    WHERE countrycode='CHN'

    GROUP BY district

    HAVING SUM(population) >5000000

    ORDER BY SUM(population) DESC ;

    -- 查询中国所有城市人口数,按从大到小排序

    SELECT NAME ,population FROM city

    WHERE countrycode='CHN'

    ORDER BY population DESC;

     

    8.0 新姿势: 倒序索引

    select * from t1 order by a asc , b desc;

    idx_a_b(a,b) ===== > idx(a asc,b desc)

     

    --- limit 子句使用

    SELECT district ,SUM(population)

    FROM city

    WHERE countrycode='CHN'

    GROUP BY district

    HAVING SUM(population) >5000000

    ORDER BY SUM(population) DESC

    LIMIT 5 OFFSET 1;

     

    SELECT district ,SUM(population)

    FROM city

    WHERE countrycode='CHN'

    GROUP BY district

    HAVING SUM(population) >5000000

    ORDER BY SUM(population) DESC

    LIMIT 1,5;

    count(*)和count(1)的区别:

    count(*)用到局和索引 count(1)全表扫描

    多表查询

    departments # 部门表

    dept_no(部门编号),

    dept_name(部门名称)

    dept_emp #部门-员工关系表

    emp_no(员工编号),

    dept_no(部门编号),

    from_date,to_date

    dept_manager #部门-经理关系表

    from_date(任职起始)

    to_date(任职结束),

    dept_no(部门编号),

    emp_no(员工编号)

    employees #员工表

    emp_no(员工编号),

    birth_date(生日),

    first_name(名),

    last_name(姓),

    gender(性别),

    hire_date(离职日期)

    salaries #薪水表

    emp_no(员工编号),

    salary(年薪),

    from_date(起始日期),

    to_date(结束日期)

    titles #职称表

    emp_no(员工编号),

    title(职称),

    from_date(起始时间),

    to_date(结束时间)

     

    -- 说明: 别名应用

    表别名: 在任意子句中调用表名时,都可以使用别名替代

    列别名: 在having和order by子句中可以调用

     

    -- 多表连接工作逻辑

    1. 优化器,在内连接中,选择驱动表

    (1) 多张表时,从左到右,查看表中索引情况,有索引选为驱动表

    (2) 如果第一张没有,直到找到第一只张表有索引的表作为驱动表

    (3) 如果都没有,则选择行数少的表

     

    2. 多表连接算法

    SNLJ

    BNLJ

    BKAJ

    3. 优化重点

    强制“小表”为驱动表(left join会强制使用左表为驱动表,right join 同理)

    建立合适的索引

    开启优化算法

    set global

    optimizer_switch='batched_key_access=ON,mrr_cost_based=

    off';

    4. letf join 优化not in 语句

     

     

     

     

  • 相关阅读:
    postgresql----UNION&&INTERSECT&&EXCEPT
    postgresql----JOIN之多表查询
    postgresql----ANY/SOME&&ALL
    在页面获取本地电脑IP
    redis-Jedis连接集群
    redis-存储命令
    redis-启用命令
    springboot-整合freemarker
    springboot-发布jar包
    springboot-实现log4j的AOP切面
  • 原文地址:https://www.cnblogs.com/zh-dream/p/13022614.html
Copyright © 2011-2022 走看看