[MySQL] 01- Basic sql
准备
一、配置
1. 登录:mysql -u root -p
2. phpMyAdmin创建数据库,并导入.sql文件。
3. 支持中文:set names utf8;
二、面试题
参考:面试宝典----数据库【一些经典的问题】
基础教程
详见: http://www.runoob.com/sql/sql-select.html
一、查询
SELECT name,country FROM Websites;
SELECT DISTINCT country FROM Websites;
SELECT * FROM websites ORDER BY country,alexa DESC; # 不写明ASC DESC的时候,默认是ASC
SELECT * FROM Websites LIMIT 2; # MS使用select top, oracle使用rownum
SELECT * FROM Websites WHERE id=1;
- 常见运算符
运算符 | 描述 |
---|---|
= | 等于 |
<> | 不等于。注释:在 SQL 的一些版本中,该操作符可被写成 != |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
BETWEEN | 在某个范围内 |
LIKE | 搜索某种模式 |
IN | 指定针对某个列的多个可能值 |
IS NULL | e.g. where comm is null Goto: SQL NULL 函数 |
REGEXP | 操作正则表达式 |
补充 - 逻辑运算
Select * from emp where sal > 2000 and sal < 3000;
Select * from emp where sal > 2000 or comm > 500;
select * from emp where not sal > 1500;
- 模糊查询
- LIKE
Select * from emp where ename like 'M%';
Select * from emp where ename like '[CK]ars[eo]n'; # 将搜索下列字符串:Carsen、Karsen、Carson 和 Karson(如 Carson)
查询 EMP 表中 Ename 列中有 M 的值,M 为要查询内容中的模糊信息。
'%a' | 以a结尾的数据 |
'a%' | 以a开头的数据 |
'%a%' | 含有a的数据 |
‘_a_’ | 三位且中间字母是a的 |
'_a' | 两位且结尾字母是a的 |
'a_' | 两位且开头字母是a的 |
- SQL [charlist] 通配符
SELECT * FROM websites WHERE name REGEXP '^[GFs]';
SELECT * FROM Websites WHERE name REGEXP '^[^A-H]'; # 选取 name 不以 A 到 H 字母开头的网站。第一个^是开头的意思;第二个^表否定。
- Between 作用于 '字符串' 和 '日期'
SELECT * FROM Websites WHERE name BETWEEN 'A' AND 'H';
SELECT * FROM Websites WHERE name NOT BETWEEN 'A' AND 'H'; SELECT * FROM access_log WHERE date BETWEEN '2016-05-10' AND '2016-05-14';
详情请见:SQL Date 函数
二、插入
INSERT INTO websites (name, url, alexa, country) VALUES ('百度', 'https://www.baidu.com/', '4', 'CN');
# 前后一一对应即可。
三、更新
UPDATE websites SET alexa='5000', country='USA' WHERE name='菜鸟教程';
# MySQL中强制在update 语句后携带 where 条件,否则就会报错。set sql_safe_updates=1; 表示开启该参数
四、删除
DELETE FROM websites WHERE name='百度' AND country='CN';
DELETE |
DELETE FROM test |
删除 所有内容,不保留表的定义,释放空间。 | |
TRUNCATE |
TRUNCATE test; |
删除 所有内容,保留表的定义,释放空间。 | |
DROP |
DROP test; |
仅删除 所有内容,保留表的定义,不释放空间。 DROP INDEX / TABLE / DATABASE <name> |
五、Create Db then Table
CREATE DATABASE my_db; CREATE TABLE Persons
(
PersonID int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
);
详情请见:SQL通用数据类型,SQL 用于各种数据库的数据类型
高级教程
一、别名
- 一个表
SELECT name AS n, country AS c FROM Websites; SELECT name, CONCAT(url, ', ', alexa, ', ', country) AS site_info FROM Websites;
- 多个表
SELECT w.name, w.url, a.count, a.date
FROM Websites AS w, access_log AS a
WHERE a.site_id=w.id and w.name="菜鸟教程";
二、SQL JOIN
- 四种类型
INNER JOIN | 如果表中有至少一个匹配,则返回行 |
LEFT JOIN | 即使右表中没有匹配,也从左表返回所有的行 (左边没空格) |
RIGHT JOIN | 即使左表中没有匹配,也从右表返回所有的行 (右边没空格) |
FULL JOIN | 只要其中一个表中存在匹配,则返回行 (两边可能都有空格) |
- 四个示范
Ref: SQL的各种连接Join详解
select * from Table A inner join Table B on Table A.id=Table B.id
select * from Table A left join Table B on Table A.id=Table B.id
select * from Table A right join Table B on Table A.id=Table B.id
select * from Table A full outer join Table B on Table A.id=Table B.id
三、合并表 UNION
默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SELECT country, name FROM Websites
WHERE country='CN'
UNION ALL
SELECT country, app_name FROM apps
WHERE country='CN'
ORDER BY country;
四、从一个表 copy info to 另一个表
MySQL 数据库不支持 SELECT ... INTO 语句,但支持 INSERT INTO ... SELECT 。
INSERT INTO websites (name, country) SELECT app_name, country FROM apps;
备份表数据:CREATE TABLE emp AS SELECT * FROM scott.emp
还原表数据:INSERT INTO emp SELECT * FROM scott.emp
约束(Constraints)
一、NOT NULL | DEFAULT
- 非空约束
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
- 默认值约束
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255) DEFAULT 'Sandnes'
OrderDate date DEFAULT GETDATE()
)
- 自增属性
CREATE TABLE Persons
(
ID int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (ID)
)
默认地,AUTO_INCREMENT 的开始值是 1,每条新记录递增 1。如果是自定义起始值,如下操作。
ALTER TABLE Persons AUTO_INCREMENT=100
二、唯一 | 主键 | 外键
- UNIQUE
[1] 唯一标识
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName)
)
注释:
(a) 命名 UNIQUE 约束,
(b) 定义多个列的 UNIQUE 约束
[2] 撤销约束
ALTER TABLE Persons
DROP INDEX uc_PersonID # 撤销 UNIQUE
- PRIMARY KEY
[1] PRIMARY KEY - 类似 UNIQUE
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)
[2] 撤销约束
ALTER TABLE Persons
DROP PRIMARY pk_PersonID # 撤销 PRIMARY KEY
- FOREIGN KEY
[0] 什么是外键
一个表中的 FOREIGN KEY 指向另一个表中的 PRIMARY KEY。
"Orders" 表中的 "P_Id" 列指向 "Persons" 表中的 "P_Id" 列。
["Persons" 表]
P_Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Hansen | Ola | Timoteivn 10 | Sandnes |
2 | Svendson | Tove | Borgvn 23 | Sandnes |
3 | Pettersen | Kari | Storgt 20 | Stavanger |
["Orders" 表]
O_Id | OrderNo | P_Id |
---|---|---|
1 | 77895 | 3 |
2 | 44678 | 3 |
3 | 22456 | 2 |
4 | 24562 | 1 |
[1] 创建外键
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id), # 这里没有命名
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
)
[2] 撤销外键
ALTER TABLE Orders
DROP FOREIGN KEY fk_PerOrders
三、ALTER
- 为了添加一列
Switch to table Persons. Then, 添加一列: data。
ALTER TABLE Persons
ADD DateOfBirth date
- 为了改变列的数据类型
ALTER TABLE Persons
ALTER COLUMN DateOfBirth year
四、CHECK - 限制列中的值范围
[1] 创建约束
(a) 命名 CHECK 约束,
(b) 并定义多个列的 CHECK 约束
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes')
)
[2] 撤销约束
ALTER TABLE Persons
DROP CHECK chk_Person
五、索引
在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。
用户无法看到索引,它们只能被用来加速搜索/查询。
为Persons表中的LastName, FirstName列做索引。
CREATE INDEX PIndex ON Persons (LastName, FirstName)
SQL函数
一、SQL Aggregate 函数
- 列平均值
AVG() - 返回某一列的平均值
SELECT site_id, count FROM access_log WHERE count > (SELECT AVG(count) FROM access_log);
- 列求和
SUM() - 返回总和
SELECT SUM(count) AS nums FROM access_log;
- 行数
COUNT() - 返回行数 - 因为是新列,当然需要AS。
SELECT COUNT(count) AS nums FROM access_log WHERE site_id=3;
- 行类别数
SELECT COUNT(DISTINCT site_id) AS nums FROM access_log;
- 首、尾
FIRST() - 返回第一个记录的值 - 使用Limit=1关键字
LAST() - 返回最后一个记录的值 - 使用ORDER BY id DESC,以及Limit=1
- 极大极小值
MAX() - 返回最大值,MIN() - 返回最小值
SELECT MAX(alexa) AS max_alexa FROM Websites;
SELECT MIN(alexa) AS min_alexa FROM Websites;
二、GROUP BY 语句
- 一张表
Ref: SQL中Group By的使用【写得不错】
结合聚合函数,根据一个或多个列对结果集进行分组。
[1] 任务:根据 '类别' 统计各个 ‘类别' 的 '数量'。
[2] 方案:注意这里把摘要撇在了一边儿。
select 类别, sum(数量) as 数量之和
from A
group by 类别
[3] 结果:实际上就是分类汇总。
- 两张表
Ref: http://www.runoob.com/sql/sql-groupby.html
[1] 任务:统计所有网站的访问的记录数。
[2] 方案:因为不想显示id,而是需要name,所以需要 LEFT JOIN websites表。
SELECT websites.name, COUNT(access_log.aid) AS nums FROM access_log 【GROUP BY site_id】
LEFT JOIN websites 【websites只是个给出site_id对应名字的参考表】
ON access_log.site_id=websites.id
GROUP BY websites.name;
三、HAVING 子句
- Having 与 Where 的区别
where 子句:是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,where条件中不能包含聚组函数,使用where条件过滤出特定的行。
having 子句:是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件过滤出特定的组,也可以使用多个分组标准进行分组。
- 分组之后的筛选
select 类别, sum(数量) as 数量之和 from A
group by 类别
having sum(数量) > 18
一张表,分组后只需要 sum > 18 的。
- Having 和 Where 的联合使用
分组前筛选一次;分组后筛选一次。
select 类别, SUM(数量)from A
where 数量 gt;8
group by 类别
having SUM(数量) gt; 10
四、COMPUTE
- 是什么
Ref: SQL中Group By的使用【写得不错】
compute子句能够观察“查询结果”的数据细节或统计各列数据(如例10中max、min和avg),返回结果由select列表和compute统计结果组成。
- 如何用
对阶段性结果表的再次以统计计算。
select *
from A
where 数量>8
compute max(数量),min(数量),avg(数量)
- 看结果
Compute ... By
select *
from A
where 数量>8
order by 类别
compute max(数量),min(数量),avg(数量) by 类别
执行结果:
五、SQL Scalar 函数
- 大小写转换
UCASE() - 将某个字段转换为大写;LCASE() - 将某个字段转换为小写
SELECT UCASE(name) AS site_title, url FROM Websites; SELECT LCASE(name) AS site_title, url FROM Websites;
- 字段部分显示
MID() - 从某个文本字段提取字符,MySql 中使用
SELECT MID(name,1,4) AS ShortTitle FROM Websites;
- 字段的长度
LENGTH() - 返回某个文本字段的长度
SELECT name, LENGTH(url) as LengthOfURL FROM Websites;
- 四舍五入
ROUND() - 对某个数值字段进行指定小数位数的四舍五入
返回参数X的四舍五入的有 D 位小数的一个数字。如果D为0,结果将没有小数点或小数部分。
mysql> select ROUND(1.298, 1);
-> 1.3
mysql> select ROUND(1.298, 0);
-> 1
- 当前时间
NOW() - 返回当前的系统日期和时间,日期加时间的完全格式。
SELECT name, url, Now() AS date FROM Websites;
FORMAT() - 格式化某个字段的显示方式,以自定义格式显示时间
SELECT name, url, DATE_FORMAT(Now(),'%Y-%m-%d') AS date FROM Websites;
扩展练习
#!/usr/bin/env python3
# -*- coding: utf-8 -*- import pandas as pd # Please update .csv path here before running this .py.
str_path = './data_analyst_sample_data.csv'
cols = ["week_sold",'price','num_sold','store_id','product_code','department_name'] dataset=pd.read_csv(str_path,header=None, sep=',',names=cols) #######
# Q1
#######
total_price = 0.0
for i in range(1,len(dataset)):
if (dataset['department_name'][i] == 'BEVERAGE'):
each_price = float(dataset['price'][i]) * float(dataset['num_sold'][i])
each_price = round(each_price, 2)
total_price += each_price print("Total price is %.2f" % total_price)
print("") ###############################################################################
# SELECT SUM(price*num_sold) AS sales FROM <table name> where department_name='BEVERAGE'
############################################################################### from collections import Counter total_counts = Counter()
for i in range(1,len(dataset)):
product_code = dataset['product_code'][i]
total_counts[product_code] += 1 #print(total_counts)
print("There are %d unique products in the store." % len(total_counts) )
print("") ###############################################################################
# SELECT product_code, COUNT(*) FROM <table name> GROUP BY product_code
############################################################################### #######
# Q2
#######
from collections import Counter
from decimal import *
#from datetime import datetime #def convert_to_month(week_sold):
# time_str = week_sold
# time = datetime.strptime(time_str, '%Y-%m-%d')
# return time.strftime('%Y-%m') total_counts = Counter()
for i in range(1,len(dataset)):
# month_sold = convert_to_month(dataset['week_sold'][i])
store_id = dataset['store_id'][i]
product_code = dataset['product_code'][i] each_price = float(dataset['price'][i]) * float(dataset['num_sold'][i])
total_counts[store_id, product_code] += Decimal(each_price/3).quantize(Decimal('0.00')) print(total_counts) ###############################################################################
# SELECT store_id, product_code, round(SUM(price*num_sold)/3.0, 2) FROM <table name> GROUP BY store_id
############################################################################### # Save
import csv
row = ['store_id', 'product_code', 'average_monthly_revenue']
out = open("result.csv", "a", newline = "")
csv_writer = csv.writer(out, dialect = "excel")
csv_writer.writerow(row) row = ['store_id', 'product_code', 'average_monthly_revenue'] for k, v in total_counts.items():
row = [k[0], k[1], v]
out = open("result.csv", "a", newline = "")
csv_writer = csv.writer(out, dialect = "excel")
csv_writer.writerow(row)
高级特性
一、CASE...WHEN...[ELSE]...END
- 判断三角形类型
SELECT
CASE
WHEN A + B > C THEN
CASE
WHEN A = B AND B = C THEN 'Equilateral'
WHEN A = B OR B = C OR A = C THEN 'Isosceles'
WHEN A != B AND B != C OR A != C THEN 'SCALENE'
END
ELSE
'Not A Triangle'
END
FROM TRIANGLES;
- case 语句
SELECT id, (case sex
when ' ' then 'bbbbb'
when null then 'aaaaa'
else sex
end) as sex
FROM aa;
二、concat 拼接字符串
- "前后" 加括号
SELECT concat( NAME, concat("(",concat( substr(OCCUPATION,1,1), ")")) ) FROM OCCUPATIONS ORDER BY NAME ASC;
SELECT "There are a total of ", count(OCCUPATION), concat(lower(occupation),"s.") FROM OCCUPATIONS GROUP BY OCCUPATION ORDER BY count(OCCUPATION), OCCUPATION ASC
三、变量
- "横向" 列出来
set @r1=0, @r2=0, @r3=0, @r4=0;
select min(Doctor), min(Professor), min(Singer), min(Actor)
from(
select case when Occupation='Doctor' then (@r1:=@r1+1)
when Occupation='Professor' then (@r2:=@r2+1)
when Occupation='Singer' then (@r3:=@r3+1)
when Occupation='Actor' then (@r4:=@r4+1)
end as RowNumber,
case when Occupation='Doctor' then Name end as Doctor,
case when Occupation='Professor' then Name end as Professor,
case when Occupation='Singer' then Name end as Singer,
case when Occupation='Actor' then Name end as Actor
from OCCUPATIONS
order by Name
) Temp
group by RowNumber;
- 其他符号
一个以at符号(@)开头的标识符表示一个本地的变量或者参数。
一个以数字符号(#)开头的标识符代表一个临时表或者过程。
一个以两个数字符号(##)开头的标识符标识的是一个全局临时对象。
四、嵌套
SET sql_mode = '';
SELECT Start_Date, End_Date
FROM
(SELECT Start_Date FROM Projects WHERE Start_Date NOT IN (SELECT End_Date FROM Projects)) a,
(SELECT End_Date FROM Projects WHERE End_Date NOT IN (SELECT Start_Date FROM Projects)) b
WHERE Start_Date < End_Date
GROUP BY Start_Date
ORDER BY DATEDIFF(End_Date, Start_Date), Start_Date
sql_mode="",即强制不设定MySql模式(如不作输入检测、错误提示、语法模式检查等)应该能提高性能,但有如下问题:
如果插入了不合适数据(错误类型或超常),mysql会将数据设为“最好的可能数据”而不报错,如:
/数字 | 0/可能最小值/可能最大值 |
/字符串 | 空串/能够存储的最大容量字符串 |
/表达式 | 返回一个可用值(1/0-null) |
所以,解决办法是:所有列都要采用默认值,这对性能也好。
[MySQL] 01- Basic sql的更多相关文章
- mysql(数据库,sql语句,普通查询)
第1章 数据库 1.1 数据库概述 l 什么是数据库 数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储起来,用户可以对数据库中的数据进行增加,修改,删除及查询操作. l 什 ...
- 技术分析 | 浅谈在MySQL体系下SQL语句是如何在系统中执行的及可能遇到的问题
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 SQL语句大家并不陌生,但某种程度上来看,我们只是知道了这条语句是什么功能,它可 ...
- MySQL 常用的sql语句小结(待续)
mysql 常用的sql语句 1.查看数据库各个表中的记录数 USE information_schema; SELECT table_name,table_rows FROM tables WHER ...
- mysql使用基础 sql语句(一)
csdn博文地址:mysql使用基础 sql语句(一) 点击进入 命令行输入mysql -u root -p,回车再输入密码,进入mysql. 终端命令以分号作为一条语句的结束,可分为多行输入,只需 ...
- MySQL命令执行sql文件的两种方法
MySQL命令执行sql文件的两种方法 摘要:和其他数据库一样,MySQL也提供了命令执行sql脚本文件,方便地进行数据库.表以及数据等各种操作.下面笔者讲解MySQL执行sql文件命令的两种方法,希 ...
- MYSQL导入导出.sql文件
MYSQL导入导出.sql文件 一.MYSQL的命令行模式的设置:桌面->我的电脑->属性->环境变量->新建->PATH=“:path\mysql\bin;”其中p ...
- 【转载】MySQL被慢sql hang住了,用shell脚本快速清除不断增长的慢sql的办法
原文地址:MySQL被慢sql hang住了,用shell脚本快速清除不断增长的慢sql的办法 作者:mchdba 某个初级dba误删index,mysql漫山遍野全是10S以上的慢sql,mysql ...
- MySQL与NoSQL——SQL与NoSQL的融合
来源:http://www.cnblogs.com/sunli/archive/2011/05/11/mysql-nosql.html 写这一篇内容的原因是MySQL5.6.2突然推出了memcach ...
- 监控mysql执行的sql语句
linux平台 监控mysql执行的sql语句 为了做好配合开发做性能和功能测试,方便监控正在执行的sql语句, 可以在/etc/mysqld中添加如下: log =/usr/local/mys ...
- MySQL的常用SQL语句.md
修改密码 这是常见的大家一般都要用的 首先 安装成功了打开cmd --> mysql -u root -p -->输入你的密码 修改mysql root用户密码 格式 ...
随机推荐
- Java编程的逻辑 (66) - 理解synchronized
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- Spring面试问题集锦
Q. 对于依赖倒置原则(Dependency Inversion Principle,DIP),依赖注入(Dependency Injection,DI)和控制反转(Inversion of Cont ...
- r语言 列出所有变量
你希望知道目前工作空间中存在哪些已定义的变量和函数. 解决方案 使用ls函数,或者使用ls.str函数了解每个变量更详细的信息. 讨论 ls函数可以显示当前工作空间中所有对象的名称:> x &l ...
- HOW-TO GEEK SCHOOL
This How-To Geek School class is intended for people who want to learn more about security when usin ...
- 关于使用QTcpSocket的一些总结
QTcpSocket类的方法connectToHost会泄露内存,即使把调用这个方法的QTcpSocket实例delete掉,内存也不会释放!反复connectToHost会导致段错误,十分危险.必须 ...
- ESD保护芯片BAT54S/BAV99和电平转换芯片SN74AVC1T45
如下两图是terasic公司DE2-115部分原理图截图,其中有两个芯片引起了笔者的注意,一个是SN74AVC1T45和BAT54S,下面说说这两个芯片利用的好处和借鉴之处. 先讲一下BAV99.手册 ...
- WDCP面板V3新版本安装与体验记录
WDCP面板V3版本看介绍变动还是比较大的,比如从底层重新架构,以及我们需要的PHP.MYSQL.NGINX等版本都是使用较新稳定版本,支持CENTOS5-7发行版本环境,至于后台界面的友好度有点扁平 ...
- 关于Unity中Mecanim动画的动画状态代码控制与代码生成动画控制器
对于多量的.复杂的.有规律的控制器使用代码生成 动画状态代码控制 1:每个动画状态,比如进入状态,离开状态, 等都有可能需要代码来参与和处理,比如,进入这个动画单元后做哪些事情,来开这个动画单元后做哪 ...
- [转]java加密算法简要介绍
本篇内容简要介绍BASE64.MD5.SHA.HMAC几种加密算法. BASE64编码算法不算是真正的加密算法. MD5.SHA.HMAC这三种加密算法,可谓是非可逆加密,就是不可解密 ...
- JUnit教程
测试是检查应用程序是否是工作按照要求,并确保在开发者水平,单元测试进入功能性的处理.单元测试是单一实体(类或方法)的测试. 单元测试在每一个软件公司开发高品质的产品给他们的客户是十分必要的. 单元测试 ...