mysql常用语句及关键字

一、常用sql语句

注意,关键字和函数最好大写,字段和表名小写,这样很容易区分。

1.创建数据库t_user
CREATE  DATABASE t_user;

2.删除数据库t_user
DROP DATABASE t_user;

3.使用数据库t_user:   USE t_user;
显示数据库中的表:  SHOW TABLES;

数据表命名

表名的命名规范为表名可以用 t_ 、tb_的前缀,或者是业务模块前缀。比如t_order。

有些项目也会使用 tt_、tm_、 ts_ 等前缀,根据项目的习惯命名就好了。

参考自:https://www.codetd.com/fr/article/13668245

 

 创建数据表

* mysql建表:

详情见: https://www.cnblogs.com/expiator/p/16542232.html

* 查看建表语句DDL:

SHOW CREATE TABLE 表名

 * 复制表结构: 新建表A,复制表B的结构:

create  table 表A like 表B

 * 找出Mysql表在哪个库: 

-- 找出Mysql表在哪个库
SELECT table_schema FROM information_schema.TABLES WHERE table_name = '表名字';

 

新增数据/更新数据

5.修改字段,使用 ALTER TABLE CHANGE :

ALTER TABLE t_user_agent CHANGE agent_id  agent_number VARCHAR(25) COMMENT '备注说明'

注意:修改字段,记得加上COMMENT 备注。


5.1添加字段,使用 ALTER TABLE  ADD:

ALTER  TABLE  t_user_agent  ADD  merchant_id  VARCHAR(25); 

在指定位置(比如某一列的字段后面)添加字段,可以使用AFTER,如下:

ALTER  TABLE  t_user_agent  ADD  duction_date  DATE  COMMENT '税期'  AFTER  duction_month ;

注意:新增字段,如果字段是NOT NULL的,最好加上DEFAULT默认值,或者是UPDATE更新历史数据中新增字段的值。

因为历史数据是不存在这个新增字段的,查询做字段映射时会报错。

 

5.2 删除字段,使用  ALTER TABLE  DROP  COLUMN :

ALTER TABLE t_user_agent   DROP COLUMN  user_id

6.删除数据表 t_sys_role
DROP TABLE  IF EXISTS   t_sys_role;
6.插入数据
INSERT  INTO  t_sys_role   VALUES(1,'0','管理员','admin');


7.查询数据
SELECT * FROM t_sys_role;

8.修改数据
UPDATE  t_sys_role  SET role='user' WHERE id=1;
注意:使用UPDATE进行更新时,SET多个字段,使用逗号,隔开,而不是用AND。

正确的语句如下:

UPDATE  t_sys_user SET fname='lin' , fscore='88' WHERE fid='3'

如果使用以下sql,可能会出现问题。

UPDATE  t_sys_user SET fname='lin' AND fscore='88' WHERE fid='3'


9.删除数据
DELETE FROM t_sys_role  WHERE id=1;

注意:在使用DELETE和UPDATE之前,一定一定要先SELECT查询一下,将要删除的是哪些数据!!!

最好在查询后,还"导出数据"进行备份,然后再进行数据变更。

 二、建表关键字

0. constraints :SQL 约束
约束用于限制加入表的数据的类型。
可以在创建表时规定约束(通过 CREATE TABLE 语句),或者在表创建之后也可以(通过 ALTER TABLE 语句)。
比如,not null,unique,PRIMARY KEY,foreign key,default都属于约束
可以用CONSTRAINT 命名约束。如下,命名外键约束为fk_PerOrders。

CREATE TABLE t_orders
(
Id_O int NOT NULL,
OrderNo int NOT NULL,
Id_P int,
PRIMARY KEY (Id_O),
CONSTRAINT fk_PerOrders FOREIGN KEY (Id_P)
REFERENCES Persons(Id_P)
)


1.PRIMARY KEY 主键
主键表示该列值在表中是唯一的,不可以有重复。
主键必须包含唯一的值。主键列不能包含 NULL 值。
每个表都应该有一个主键,并且每个表只能有一个主键。

主键的命名规范为pk_开头。

一般是在建表的时候指定了主键,就会创建主键索引。

主键索引:它是一种特殊的唯一索引,不允许有NULL值。

复合主键:就是指表的主键含有一个以上的字段组成。比如 primary key (name,age)

复合主键,只有在查询复合主键的第一个字段时,才会走主键索引。其他的字段,都是全表扫描。

联合主键:多个表的主键联合,对应另一张表的一个主键。


2.AUTO_INCREMENT自增
auto_increment 就是对主键自动增加编号的。

3.UNSIGNED无符号
unsigned是无符号的意思,代表该字段没有正负。

4.字段数据类型中,varchar和char的区别是什么?
varchar长度是可变的,能够节省空间。比如说存储"abc",CHAR(10)需要10个字符的空间来储存,而VARCHAR(10)只需要3个字符的空间。

5.FOREIGN KEY  外键约束
一个表中的 FOREIGN KEY 指向另一个表中的 PRIMARY KEY。
如下示,Id_P是Orders表的外键,也是Persons表的主键。可以用CONSTRAINT 命名约束。命名外键约束为fk_PerOrders。

CREATE TABLE Orders
(
Id_O int NOT NULL,
OrderNo int NOT NULL,
Id_P int,
PRIMARY KEY (Id_O),
CONSTRAINT fk_PerOrders FOREIGN KEY (Id_P)
REFERENCES Persons(Id_P)
)

6.UNIQUE 约束, 使数据库表中的某一列或某几列的里面的内容不重复

7. CREATE TABLE   SELECT  
根据查询结果创建表格
CREATE  TABLE  t_user2  (SELECT a.* FROM  user1  a  WHERE a.ID='SYSTEM')

8.复制表数据到另一个张

INSERT INTO t_user2 SELECT * FROM t_user;

9. 修改表名

ALTER TABLE t_user2 RENAME TO t_user;



 

三、查询关键字

0. IS NULL和IS NOT NULL。

不能使用 字段= NULL 或 字段!= NULL 在列中查找数据。可以使用以下格式:

WHERE 字段 IS NOT NULL

NULL值查询使用IS NULL和IS NOT NULL查询,而空值('')可以使用=或者!=、<、>、等算术运算符。

在实际开发中,建议使用空值。使用WHERE IS NULL不走索引。

Mysql里面NULL和空值的区别,详情见: https://www.cnblogs.com/lonelyxmas/p/10371120.html

 

0.  % 通配符,表示一个或多个字符
如下示,查询170开头的电话号码。
SELECT  order,age,sex FROM phone_info  WHERE  phoneNumber LIKE  "170%"
最好不要用左模糊,会因为扫全表而变慢。

1. AS  别名,其中 AS 可以省略
普通的表可以取简单的别名a,b,c。。而任意查询出来的结果,也可以通过取别名作为一个表来使用。
比如,以下将(SELECT * FROM user WHERE id=1  )的查询结果,通过取别名来使用
SELECT a.username FROM (SELECT * FROM user WHERE id=1  )  a;

字段,同样也可以通过AS取别名。
2.  JOIN   连接:用于根据两个或多个表中的列之间的关系,从这些表中查询数据。通过Inner JOIN  ...  On   实现。

JOIN其实就是把两(多)张表合起来,从大表里面查询的一个操作。
如下示,查找Persons中Id_P和Orders表中Id_P相同的数据。

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
INNER JOIN Orders
ON Persons.Id_P = Orders.Id_P
ORDER BY Persons.LastName


各种JOIN的区别:
JOIN: 如果表中有至少一个匹配,则返回行
INNER JOIN 与 JOIN 是相同的。
LEFT JOIN: 即便关联条件不符合,左边表的数据一定会存在合并后的大表中。
RIGHT JOIN: 即便关联条件不符合,右边表的数据一定会存在合并后的大表中。
FULL JOIN: 只要其中一个表中存在匹配,就返回行。

JOIN使用要点:小表驱动大表。

LEFT JOIN 左连接,左边为驱动表,右边为被驱动表.
RIGHT JOIN 右连接,右边为驱动表,左边为被驱动表.
INNER JOIN 内连接, mysql会选择数据量比较小的表作为驱动表,大表作为被驱动表.


3. UNION  组合查询/联合查询
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 联合的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。
同时,每条 SELECT 语句中的列的顺序必须相同。
如下示:
SELECT Employee_Name FROM Employees_China
UNION   SELECT Employee_Name FROM Employees_USA
另外,UNION和UNION ALL区别:
默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

4.SELECT INTO   查询并插入
SELECT INTO 语句从一个表中选取数据,然后把数据插入另一个表中。
SELECT INTO 语句常用于创建表的备份复件或者用于对记录进行存档。

SELECT LastName,FirstName
INTO Persons_backup
FROM Persons


另外的,还有INSERT INTO SELECT 语句
从一个表复制数据,然后把数据插入到一个已存在的表中。目标表中任何已存在的行都不会受影响。
SQL INSERT INTO SELECT 。
我们可以从一个表中复制所有的列插入到另一个已存在的表中:
INSERT INTO TABLE2   SELECT * FROM TABLE1;

INSERT INTO table2
(column_name(s))
SELECT column_name(s)
FROM table1;

5.DISTINCT 只返回不同的值。
以下返回不同的userId,不会重复:
SELECT DISTINCT userId FROM user
DISTINCT支持单列、多列的去重方式。
单列去重的方式简明易懂,即相同值只保留1个。
多列的去重则是根据指定的去重的列信息来进行,即只有所有指定的列信息都相同,才会被认为是重复的信息。
多列去重如下 :

SELECT    count( DISTINCT user_code, user_no )    FROM    t_user


6.LIMIT  分页查询。

LIMIT X,Y  序号从0开始数,其中的X表示从第几行开始,Y表示返回几条记录。
示例:每页5行,返回第2页的数据,即返回第6~10条记录。
SELECT user_name FROM  user LIMIT 5,5

示例:查找入职员工时间排名倒数第三的员工所有信息 。

思路:倒序,然后分页查找,找到从第序号为2的开始的一条记录,就是倒数第三。

SELECT * FROM  employees  ORDER BY hire_date DESC  LIMIT 2,1

注意:Mysql并没有TOP关键字。

7.子查询

子查询的结果,可以作为另一张表使用。

8.EXISTS  指定一个子查询,检测行是否存在。

用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False

常用语法:not exists (子查询)

或者 not exists (select 1 from 表名)

select 1 from 中的1是一常量(可以为任意数值),查到的所有行的值都是它,select 1效率比select * 高。

参考资料:https://blog.csdn.net/ahesihua/article/details/84275723

示例如下:

select c_insrnc_cde, c_nme_cn
   from t_prd_ins a
where a.c_prod_no = '01'
    and not exists
(select 1
           from (select d.c_insrnc_cde, a.c_nme_cn
                   from t_prd_ins                   a,
                        tb_bas_ply_policy_rdr       c,
                        tb_bas_ply_policy_rdr_list d
                  where a.c_insrnc_cde = d.c_insrnc_cde
                    and d.c_policy_id = c.c_policy_id
                    and d.c_seq_no = c.c_seq_no
                    and c.c_reach_area = '00701'
                    ) t
          where t.c_insrnc_cde = a.c_insrnc_cde);

 

9.查看表结构、查看字段的命令,如下:
desc 表名;
show columns from 表名;
describe 表名;
show create table 表名;

10.其他:IN()、OR()、LIKE

 

四、分组关键字

1.GROUP BY   分组
将查询结果按某一列或多列的值分组
如下示:

SELECT Cno,count(sno)
FROM course
GROUP BY Cno;


一张表,一旦分组完成后,查询后只能得到组相关的信息。可以通过count(),sum(),max(),min(),avg()统计。
--统计分组后各种情况的数量

SELECT  COUNT(1),age,sex  
FROM staff WHERE 1=1 and create_date>='2018-05-07 00:00:00' GROUP BY age,sex ORDER BY age ASC


2.HAVING     分组筛选
可以对由SUM()或其它集合函数运算结果的输出进行限制。对分组添加限制条件。

当我们用到聚合函数,如sum,count后,又需要筛选条件时,可以用having,

因为WHERE是在聚合前筛选记录的,HAVING是过滤聚合函数返回的结果。

having后的判断字段必须是聚合函数返回的结果。having和group by是组合着用的。

 

如下示:

SELECT store_name, SUM(sales)
FROM Store_Information
GROUP BY store_name
HAVING SUM(sales) > 1500

HAVING有多个条件,可以用 AND 连起来

SELECT store_name, MAX(sales)
FROM t_store_information
GROUP BY store_name
HAVING MAX(sales) > 100 AND MAX(sales) <200 

 

3.COUNT(column_name) 函数返回指定列的值的数目
COUNT(DISTINCT column_name) 函数返回指定列的不同值的数目:

COUNT(1) 比 COUNT(*)的速度更快。


4.CASE...  WHEN

类似于java中的switch()语句。

有两种表现形式:

CASE
  WHEN SEX = '1' THEN ''
  WHEN SEX= '2' THEN ''
ELSE '未知' END

或者是:

CASE sex
      WHEN '1' THEN ''
      WHEN '2' THEN ''
      ELSE '未知'
  END;

可用于查询中,也可以用于变更中。

示例如下,查询示例如下:

SELECT id,name,create_time,
    (CASE WHEN status = 0 THEN '失败'
          WHEN status = 1 THEN '成功'
          WHEN status = 2 THEN '等待中'
          ELSE '其它'  END) AS result
FROM t_order

变更示例如下,变更salary表中的性别:

UPDATE salary 
SET 
  sex=CASE sex
      WHEN 'm' THEN 'f'
      ELSE 'm'
  END;

示例2,将数字型的年月拼接起来,比如,将数字字段2019和2,拼接成一个日期2019-02,

CAST(fdeduction_month AS CHAR)表示将数字类型转化为字符类型。

UPDATE t_user_duction
SET duction_date=CONCAT(duction_year, '-',
         CASE  WHEN duction_month<10 
THEN CONCAT('0',CAST(duction_month AS CHAR)) ELSE CAST(duction_month AS CHAR) END )

Case...When还可以作为COUNT的条件。
比如,count( CASE WHEN err_reason is  not null THEN 1 ELSE NULL END )表示如果err_reason不是空那么就计数1,用于计算err_reason不为空的数量。
示例:

SELECT  COUNT(*) as REQUEST_COUNT,
        COUNT( CASE WHEN err_reason is  not null THEN 1 ELSE NULL END ) as FAILURE_COUNT,
        COUNT( CASE WHEN success_reason is not null THEN 1 ELSE NULL END ) as SUCCESS_COUNT 
FROM  trace_201804 WHERE 1=1 
AND create_date>='2018-04-28 09:00:00' 
AND  create_date<'2018-04-28 09:30:00' 
GROUP BY order_day, order_code  
ORDER BY order_day ASC

 

四、字符串处理

1.CONCAT (Str1,Str2)
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。

示例如下:

SELECT name FROM user 
WHERE name LIKE CONCAT('%','ming','%')

2.GROUP_CONCAT(字段):将一个或多个字段的多行数据,把所有值合并成一行。默认按逗号,分隔

比如emp_no字段有三行数据,分别为10007、10008、10010,那么GROUP_CONCAT(emp_no)的值为合并后的 10007,10008,10010

示例:按照dept_no进行汇总,属于同一个部门的emp_no按照逗号进行连接,结果给出dept_no以及连接出的结果employees

SELECT dept_no,GROUP_CONCAT(emp_no)  as employees
FROM dept_emp
GROUP BY dept_no

如果想使用其他的分隔符 ,可以使用GROUP_CONCAT(字段  separator '分隔符') 。

示例如下:

select dept_no,group_concat(emp_no separator ';') from dept_emp group by dept_no;

 3.REPLACE() 替换

4.SUBSTRING(str,from,to) 截取字符串

str为字符串,from表示起始下标,to表示末尾下标。from和to这两个数字都包含边界。比如以下sql,表示从第一个下标到第十的下标。

获取时间字符串的年月日:

-- 结果为2019-08-07
SUBSTRING('2019-08-07 17:34:57' ,1 , 10);

获取时间字符串的年月:

SUBSTRING('2019-08-07 17:34:57' ,1 , 7)

统计每个月的数据量:

SELECT SUBSTRING(create_time ,1 , 7) , COUNT(1) 
FROM tt_order
WHERE create_time BETWEEN '2022-01-01 00:00:00' AND '2022-06-30 23:59:59'
GROUP BY  SUBSTRING(create_time ,1 , 7);

 

5.LEFT()、RIGHT().

6.CAST(字段名 AS CHAR)表示将字段转化为字符类型。

CAST(字段名 AS DECIMAL(23,2)) 表示将字段转化为小数类型,共23位,小数为2位。如果字段是以科学计数法表示的,也可以通过CAST将科学计数法转化为小数。

 

7.TRIM(字符)会同时删除字符串前后出现的空白字符

LTRIM(字串): 将所有字串开头的空白字符移除。

RTRIM(字串): 将所有字串结尾的空白字符移除。

四、日期

1. NOW():表示当前日期及时间

2. CURDATE():表示当前日期,也就是今天

CURTIME() :表示当时的时间(不包含日期)

3. DATE_SUB(CURDATE(), INTERVAL 1 DAY)   昨天

DATE_SUB(CURDATE(), INTERVAL 7 DAY)   七天前

DATE_SUB(CURDATE(),INTERVAL DAY(CURDATE())-1 DAY)   获取本月第一天

4. mysql 字符串转日期:   str_to_date('2008-4-2 15:3:28','%Y-%m-%d %H:%i:%s')

%H 两位数字形式的小时,24 小时制。

%h 两位数字形式的小时,12 小时制。

mysql的日期与字符串互相转换: https://www.cnblogs.com/gavinYang/p/11197875.html

 

5.TO_DAYS(Date date):返回从0000年(公元1年)至日期参数date的总天数

SELECT  TO_DAYS(NOW());

SELECT  TO_DAYS(str_to_date('2023-05-01','%Y-%m-%d %H:%i:%s'));

 

 

四、INDEX索引

索引对于操作者,仅仅提供创建、删除和修改的功能。操作者在增删改查过程中,系统会自动调用索引。
可以在表中创建索引,以便更加快速高效地查询数据。

索引的命名规范为idx_开头。比如idx_name

1.CREATE  INDEX 添加索引。

CREATE  INDEX 索引名  ON  表名(字段名)
创建一个简单的索引,名为 idx_name,在 t_person 表的 last_name 列,如下示:
CREATE INDEX idx_name ON   t_person(last_name)

2.ADD  INDEX  添加索引:

ALTER TABLE 表名 ADD  INDEX 索引名 (字段名1[,字段名2 …]);
例子:  ALTER TABLE   t_employee  ADD  INDEX   idx_emp_name (name);

3.SHOW  INDEX  显示索引

例如:SHOW INDEX FROM t_person

4.DROP  INDEX   删除索引

ALTER TABLE  t_test  DROP  INDEX   idx_order ;

5.RENAME INDEX  重命名索引

将t_test表的order_id_2索引,重命名为 idx_order

ALTER TABLE t_test RENAME INDEX order_id_2 TO  idx_order

联合索引:

联合索引,是指将表上的多个列作为一个索引。

CREATE INDEX idx_user ON   t_person(last_name,first_name)
或者是:

ALTER TABLE   t_test  ADD  INDEX   idx_user  (last_name,first_name);

 

唯一索引:

唯一索引,是指多个列的组合只能唯一。

ALTER TABLE tb_person ADD UNIQUE KEY uk_user_id_status (user_id,status);

或者是:

CREATE UNIQUE KEY uk_user_id_status ON tb_person(user_id,status)
或者是:

ALTER TABLE t_person ADD CONSTRAINT uk_user_id_status UNIQUE (user_id,status)

 

五、EXPLAIN  执行计划

查看SELECT语句的执行计划

在Sql语句前面加一个EXPLAIN即可。

 

EXPLAIN结果,重点看key这个字段,key表示此次查询中确切使用到的索引.
其次看 type,有没有走索引。
还可以看下 rows,扫描了多少行,扫描的行越少越好。
如果extra 中,出现了 using filesort,也要注意,尽量避免。

 

详情见: Mysql性能优化EXPLAIN

六、其他

* mysql 生成 UUID;

SELECT UUID();

* mysql 生成 UUID,并去掉横杠 -

SELECT replace(UUID(),'-','');

 

* mysql 解决主从延迟。

核心的sql,可以强制走主库。比如订单的支付状态查询、退款状态查询。

/*FORCE_MASTER*/ SELECT * FROM table_name


附录、练习题目:

基础题:   牛客网Sql实战

进阶题:  sql语句练习50题

posted on 2018-05-16 11:09  乐之者v  阅读(2396)  评论(0编辑  收藏  举报

导航