一文带你入门 SQL

本文介绍了SQL在处理大数据和数学建模中的优势,展示了如何通过SQL进行增删查改,以及如何使用WHERE、JOIN、UNION等操作简化数据处理。还涵盖了主键、外键、约束和视图等概念,以及数据导出和导入技巧。
摘要由CSDN通过智能技术生成

  同学们可以结合本人的另外一篇博客,结合着使用~
  使用 SQL 实战处理2020国赛C题数据

1. SQL 简介

SQL (Structured Query Language:结构化查询语言) 是用于用于管理关系数据库管理系统(RDBMS)。 SQL 的范围包括数据插入、查询、更新和删除,数据库模式创建和修改,以及数据访问控制。

2.优势

​ SQL 面向数据库进行 增删查改,在我们没有接触数据库的时候,如果要对数据进行处理,一般会用到 for 循环进行遍历。比如,我们有一个结构体数组(下文称为表),里面包含着名字,年龄和性别。如果我们要把性别为女的同学查找出来,我们需要使用 for 循环一遍,访问每一个结构体中的性别,进行甄别。这种方法对于几百几千条数据来说耗费时间看似没有差别,但如果是几十万,几百万条数据,时间的耗费则越来越重。

​ 再者,如果存在另外一个表,里面记录着每一同学每次考试的成绩,我们现在需要将两个表进行合并,成为一条包含着名字,性别,年龄以及成绩(假设名字唯一)的数据,这时我们就需要使用两个 for 循环来处理,并构造新的结构体来进行存储,即便其他语言比如 Python 等 不需要构造结构体,但两层的 for 循环带来的时间耗费的提高也是不容小觑的,更何况会存在更多层 for 循环的情形

​ 笔者曾参加过 2020年 的数模国赛,选择的就是大数据问题,说实话,当时没有用到过数据库,用的虽然是 Python 但 处理数据的时候,使用了许多 for 循环,耗费了许多时间,只水了个省二。贴一下当时处理处理数据的一小部分代码,可以看出,不仅数据量大而且处理逻辑复杂,还很容易出错。比赛完之后就觉得如果使用数据库来进行处理,定会有奇效的。果然,几分钟 for 才得到的数据 SQL 一两秒秒了。所以笔者很推荐准备参加数学建模并且选择大数据题目的同学,加强一下数据库的学习以及练习。

# Dep_In_Profit 企业进货税价和
# Dep_In_Price  企业进货价格和
# Dep_In_Rex  企业进货税收和
# Dep_In_Tic_T 企业进货有效发票
# Dep_In_Tic_T_R 负数票据
# Dep_In_Tic_T_S 正数票据
# Dep_In_Tic_F 企业进货无效发票
Dep_In_Profit_M = np.zeros(302)
Dep_In_Price_M = np.zeros(302)
Dep_In_Rex_M  = np.zeros(302)
Dep_In_Profit_N = np.zeros(302)
Dep_In_Price_N = np.zeros(302)
Dep_In_Rex_N  = np.zeros(302)
Dep_In_Tic_T = np.zeros(302)
Dep_In_Tic_F = np.zeros(302)
Dep_In_Tic_T_R = np.zeros(302)
Dep_In_Tic_T_S = np.zeros(302)
for i in range(0,395175):
    if In_items.iloc[i,9] == 1:
        Dep_In_Tic_T[In_items.iloc[i, 8]-124] = Dep_In_Tic_T[In_items.iloc[i, 8]-124] + 1
        if In_items.iloc[i, 6] < 0:
            Dep_In_Profit_N[In_items.iloc[i, 8]-124] = Dep_In_Profit_N[In_items.iloc[i, 8]-124] + In_items.iloc[i, 6]
            Dep_In_Price_N[In_items.iloc[i, 8]-124] = Dep_In_Price_N[In_items.iloc[i, 8]-124] + In_items.iloc[i, 4]
            Dep_In_Rex_N[In_items.iloc[i, 8]-124] = Dep_In_Rex_N[In_items.iloc[i, 8]-124] + In_items.iloc[i, 5]
            Dep_In_Tic_T_R[In_items.iloc[i, 8]-124] = Dep_In_Tic_T_R[In_items.iloc[i, 8]-124] + 1
        else:   
            Dep_In_Profit_M[In_items.iloc[i, 8]-124] = Dep_In_Profit_M[In_items.iloc[i, 8]-124] + In_items.iloc[i, 6]
            Dep_In_Price_M[In_items.iloc[i, 8]-124] = Dep_In_Price_M[In_items.iloc[i, 8]-124] + In_items.iloc[i, 4]
            Dep_In_Rex_M[In_items.iloc[i, 8]-124] = Dep_In_Rex_M[In_items.iloc[i, 8]-124] + In_items.iloc[i, 5]
            Dep_In_Tic_T_S[In_items.iloc[i, 8]-124] = Dep_In_Tic_T_S[In_items.iloc[i, 8]-124] + 1
    else:
        Dep_In_Tic_F[In_items.iloc[i, 8]-124] = Dep_In_Tic_F[In_items.iloc[i, 8]-124] + 1

3.用武之处

​ 首先是数学建模以及大数据处理方面的应用,当然这方面的应用是 SQL 相较于一般处理方法的优势所在,并且在处理多表级联关系时,SQL 显得更加简洁,for 循环或其他一般方式显得更加复杂以及更容易出错。

​ 其次在应用开发时,无论是 web 应用还是移动端 ,数据库肯定是需要的,用于前后端数据的联系,虽然平时并不会设计很大的数据量,但熟悉 SQL 的基本增删改查也是很有必要哒。

4.入门

1. 增
1.1 增加数据库
create database learn; # learn 为数据库的名称 
use learn; # 使用此数据库
set names utf8; # 设置编码
1.2 增加表
CREATE TABLE Persons # 括号里包含着每一个键的名称以及数据类型用逗号隔开
(
    PersonID  int,
    LastName  varchar(255),
    FirstName varchar(255),
    Address   varchar(255),
    City      varchar(255)
    # 可在定义之后加上一些约束,之后会提到
);
1.3 增加表中的数据
1.3.1 插入整条数据
insert into Persons # 插入整条数据的时候要与表中的键一一对应 
values (1, 'mary', 'Smith', '127.0.0.1', 'Beijing');
insert into Persons
values (3, 'mar', 'Smith', '127.0.4.1', 'Beijing');
insert into Persons
values (4, 'max', 'Smith', '127.0.6.1', 'Tianjin');
insert into Persons
values (5, 'mute', 'Rio', '127.0.6.1', 're');
insert into Persons
values (6, 'mate', 'Linda', '127.1.6.1', 'Tianjin');
insert into Persons
values (2, 'mario', 'Smith', '127.1.0.1', 'Nanjing');
1.3.2 插入指定键的数据
INSERT INTO Persons (PersonID,LastName,City) # 括号中的便是 表中的键 下面插入的 value 需要与之对应
VALUES ('mirry','Smith','Hangzhou');
2. 删
2.1 删除数据库
drop database learn; # 删库需谨慎
2.2 删除表
drop TABLE website; # 删除表
TRUNCATE TABLE table_name # 删除表的数据,表本身存在
2.3 删除索引
ALTER TABLE table_name DROP INDEX index_name; # 适用于MySQL 
DROP INDEX index_name; # 适用于 DB2/Oracle
DROP INDEX table_name.index_name; # 适用于 MS SQL Server
3. 改
3.1 表中增加列
ALTER TABLE table_name 				# 需要指定 表的名称,列的名称 以及 数据类型
ADD column_name datatype

alter table ts
add sex nvarchar(10);
3.2 表中删除列
ALTER TABLE table_name         		# 需要指定 表的名称,列的名称
DROP COLUMN column_name

alter table ts
drop column sex;
3.3 表中修改列的数据类型
# SQL Server / MS Access 适用
ALTER TABLE table_name         		# 需要指定 表的名称,列的名称,列要修改成的数据类型	
ALTER COLUMN column_name datatype

# My SQL / Oracle 适用
ALTER TABLE table_name				# 需要指定 表的名称,列的名称,列要修改成的数据类型	
MODIFY COLUMN column_name datatype

alter table ts
modify column sex nvarchar(100);
4. 查
4.1 查询所有记录
select * 				# * 便是指代所有键
from Persons;
4.2 查询指定行的记录
# 先指定数据库
use learn;
select PersonID,City from Persons;
# 直接访问
select PersonID,City from learn.Persons;
4.3 查询数据库
show databases;
4.4 查询数据库中表的名称
show tables;
5. 主键,外键,UNIQUE 约束

​ 主键是约束标识表中每一条记录的,就相当于我们的身份证,不能为 NULL , 也不能重复,在插入数据的时候必须为之指定,每一个表都有且仅有一个主键。

create table ts(
    id int,
    name varchar(25),
    primary key (id) # 指定主键 
);

​ 外键是一个表指向另一个表中的 UNIQUE KEY(唯一约束的键),假设有 每个班任课老师的表 和 每个教职工的表 这两张表。

班级任课老师表

任课老师教职工号(外键)老师班级
03C二班
01A一班
03C三班
02B四班

教职工表

老师教职工号(主键)
C03
B02
A01

​ 班级任课老师表中的 任课老师教职工号 指向 教职工表的教职工号。

​ 因此,教职工号作为 教职工的主键(PRIMARY KEY),任课老师教职工号 作为 班级任课老师表 的 外键(FOREIGN KEY)。

# 适用于 MySQL
CREATE TABLE TS
(
    id int NOT NULL,
    name varchar(25),
    P_Id int,
    primary key (id), # 指定主键 
    FOREIGN KEY (P_Id) REFERENCES TES(P_Id)
)
# 适用于SQL Server / Oracle / MS Access
CREATE TABLE TS
(
	id int NOT NULL PRIMARY KEY,
    name varchar(25),
    P_Id int NOT NULL FOREIGN KEY REFERENCES TES(P_Id)
)

​ UNIQUE 约束唯一标识数据库表中的每条记录,和主键不同,表中允许多个UNIQUE 约束出现,PRIMARY KEY 约束拥有自动定义的 UNIQUE 约束,这地方在处理数据的时候用到的时候没有太多,就当了解一下。

​ 约束的创建

create table ts(
    id int NOT NULL,
    name varchar(25),
    UNIQUE (id) # UNIQUE 约束
);
或者
create table ts(
    id int NOT NULL UNIQUE,# UNIQUE 约束
    name varchar(25)
);

​ 约束的删除

# MySQL
ALTER TABLE ts
DROP INDEX id

# SQL Server / Oracle / MS Access
ALTER TABLE Persons
DROP CONSTRAINT id

5.进阶

1. 操作符
1.1 WHERE(无法与聚合函数一起使用)

​ 之前举的一个查询为女生的同学的例子,传统方法为 for 循环,这样耗时耗力,使用 where 我们可以很简单的秒了

# 基本语法
SELECT column_name,column_name   # 需要查询的列
FROM table_name
WHERE column_name operator value;   # 这里为一些条件语句,接下来会提及
1.2 IN

​ 当我们需要查询某一键符合多个值的时候,这个便派上了用场

create table grade(
    name nchar(10),
    grade int
);
insert into grade values ('a', 100);
insert into grade values ('b', 100);
insert into grade values ('c', 90);
insert into grade values ('a', 100);
insert into grade values ('b', 95);
insert into grade values ('c', 93);

# 基本语法
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...);
# 查询名字是a,b,c中间一人的数据
select * from grade
where name in ('a','b','c');  # 括号里的元素要与键的数据类型相同
# 查询成绩是 90 93 100 之间的同学数据
select * from grade
where grade in (90, 93 ,100);
1.3 BETWEEN

​ 我们需要查询某一键符合在某一范围时,这个便派上了用场

# 基本语法
SELECT column_name(s)
FROM table_name
WHERE column_name BETWEEN value1 AND value2;

select * from grade
where grade between 95 and 100;
1.4 LIKE

​ LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式,主要就是匹配模式的书写,可能会涉及到正则表达式,下面给出 菜鸟课程 总结的通配符,对正则不熟悉的同学可参考我的另外一篇博文传送门

通配符匹配对象
%替代 0 个或多个字符
_替代一个字符
[charlist]字符列中的任何单一字符
[^charlist] 或 [!charlist]不在字符列中的任何单一字符

​ MySQL 中使用 REGEXPNOT REGEXP 运算符 (或 RLIKE 和 NOT RLIKE) 来操作正则表达式

# 查询以 c或d或e开头的同学名字的数据
select * from grade
where name REGEXP '^[cde]';

# 查询以 c到e字母开头的同学名字的数据
select * from grade
where name REGEXP '^[c-e]';

# 查询 不以 c到e字母开头的同学名字的数据
select * from grade
where name REGEXP '^[^c-e]';

# 查询一个字母的同学名字的数据
select * from grade
where name like '_';
2. SELECT DISTINCT

​ 以上面 班级任课老师表 为例,如果我们想要任课老师的教职工号,我们可以用 select 来只对 任课老师教职工号 进行选择,但查询的结果会有重复,C 的教职工号出现两次,我们可以使用 SELECT DISTINCT 进行查询而不会出现重复的情况。一个重要的特点就是每一条查询结果都各不相同。

# 查询参加考试的同学
select distinct name
from grade;

# 查询考试分数的种类
select distinct grade
from grade;

# 查询学生及其分数的种类
select distinct grade,name
from grade;
3. JOIN

​ join 用于将多个表联系在一起,大致可分为四种join方法

join 类型描述
INNER JOIN如果表中有至少一个匹配,则返回行
LEFT JOIN即使右表中没有匹配,也从左表返回所有的行
RIGHT JOIN即使左表中没有匹配,也从右表返回所有的行
FULL JOIN只要其中一个表中存在匹配,则返回行

create table TeaNo(
    name varchar(5) NOT NULL,
    Tno varchar(5) NOT NULL ,
    sex varchar(5) NOT NULL ,
    PRIMARY KEY (Tno)
);
create table Teach(
    Tno varchar(5) NOT NULL ,
    Teacher varchar(2) NOT NULL ,
    Class varchar(3) NOT NULL ,
    FOREIGN KEY (Tno) references TeaNo(Tno)

);

insert into TeaNo values ('C','03','男');
insert into TeaNo values ('B','02','男');
insert into TeaNo values ('A','01','女');
insert into TeaNo values ('D','04','女');

insert into Teach values ('03', 'C', '二班');
insert into Teach values ('01', 'A', '一班');
insert into Teach values ('03', 'C', '三班');
insert into Teach values ('03', 'B', '四班');

# inner join

select TeaNo.name,TeaNo.sex,Teach.Class
from TeaNo inner join Teach
on TeaNo.Tno = Teach.Tno;
# A,女,一班
# C,男,二班
# C,男,三班
# C,男,四班

# LEFT JOIN  B 和 D 老师都在右边找不到对应的信息但仍返回左边一行,空缺地方为NULL

select TeaNo.name,TeaNo.sex,Teach.Class
from TeaNo left outer join Teach
on TeaNo.Tno = Teach.Tno;
# A,女,一班
# B,男,
# C,男,二班
# C,男,三班
# C,男,四班
# D,女,

# Right JOIN
select TeaNo.name,TeaNo.sex,Teach.Class
from TeaNo right outer join Teach
on TeaNo.Tno = Teach.Tno;
# C,男,二班
# A,女,一班
# C,男,三班
# C,男,四班

# FULL JOIN 似乎语法并不支持
4. 别名

​ 在进行查询时,可以通过创建别名让列名称或者表名称的可读性更强。

# 列的别名
SELECT name AS TeacherName
FROM TeaNo;

# 表的别名 多用于多表查询时
SELECT name
FROM TeaNo AS TeacherName;
5. SQL 函数

​ 在数据处理上,正是由于这些可以直接使用的函数,让数据处理更加简便,下列是菜鸟课程上总结的函数

函数名作用
FORMAT()格式化某个字段的显示方式
LEN()返回某个文本字段的长度
ROUND()对某个数值字段进行指定小数位数的四舍五入
UCASE()将某个字段转换为大写
LCASE()将某个字段转换为小写
AVG()返回平均值
COUNT()返回行数
NOW()返回当前的系统日期和时间
FIRST()返回第一个记录的值
LAST()返回最后一个记录的值
MAX()返回最大值
MID()从某个文本字段提取字符,MySql 中使用
SubString(字段,1,end)从某个文本字段提取字符
MIN()返回最小值
SUM()返回总和
# FORMAT() 括号里的元素都是必须的
SELECT FORMAT(column_name,format) FROM table_name; 

# 得到系统时间
select date_format(NOW(),'%Y-%m-%d') As data;
6. HAVING

​ 由于WHERE 关键字无法与聚合函数一起使用,因此引入Having,HAVING 子句可以让我们筛选分组后的各组数据。

# 基本语法
SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value;

# aggregate_function(column_name) 为聚合函数,不能与 where 连用
7. Union 与 Union All

​ 二者用于合并两个或多个 SELECT 语句的结果。

​ 注意事项:UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。

​ 二者不同之处:Union 用于取并集去重,Union All 用于取并集不去重。

create table country1(
    Name varchar(10),
    Eng varchar(10)
);
create table country2(
    Name varchar(10),
    Eng varchar(10),
    amount int
);
insert into country1 values ('中国', 'CN');
insert into country1 values ('美国', 'USA');
insert into country1 values ('英国', 'UK');
insert into country1 values ('日本', 'Japan');
insert into country2 values ('德国','German',100);
insert into country2 values ('澳大利亚','Australia',100);
insert into country2 values ('俄罗斯','Russia',100);
insert into country2 values ('德国','German',100);
# 取并集 去重
select Name,Eng
from country1
UNION
select Name,Eng
from country2;
# 取并集不去重
select Name,Eng
from country1
UNION ALL
select Name,Eng
from country2;
8.日期问题

​ 日期处理问题是对数据进行提取,分类的重要环节,比如,在数学建模中,我们经常需要对一家公司的收入按月份或者年份进行提取,数据库内置的函数就会有奇效。下列是菜鸟课程总结的一些函数。

函数名称函数用处
DATE(date)提取 date 中的日期部分
DATE_ADD(date,INTERVAL expr type)从日期加上指定的时间间隔。date 为 合法的日期 ,expr 为 指定的时间间隔
DATE_FORMAT()用于以不同的格式显示日期/时间数据。
DATE_SUB(date,INTERVAL expr type)从日期减去指定的时间间隔。date 为 合法的日期 ,expr 为 指定的时间间隔
DATEDIFF(date1,date2)返回两个日期之间的天数date1 和 date2 参数是合法的日期或日期/时间表达式
EXTRACT()用于返回日期/时间的单独部分,如年,月,日
9. 视图

​ 根据本人的理解,视图就是将一个或者多个表之间关联起来并作为一个虚拟表返回,这个虚拟表是动态改变的,我们下次再次将多个表关联起来时只需要操作视图即可。

​ 在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。您可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,也可以呈现数据,就像这些数据来自于某个单一的表一样。

​ 视图总是显示最新的数据!每当用户查询视图时,数据库引擎通过使用视图的 SQL 语句重建数据。

​ 视图所查询出来的数据只能进行查看,不能增删改。

# 基本语法
CREATE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition
10. AND OR

​ 将多个条件结合进行筛选

​ and : 连接的条件都需要满足

​ or : 连接的条件有一个满足就可

11. GROUP BY 和 ORDER BY

​ ORDER BY 为排序操作,根据指定的属性来进行排序,可以指定升序以及降序

# 默认为升序排列
select *
from grade
order by grade;

# 降序排列,先按成绩,成绩一样再按分数
select *
from grade
order by grade,name desc;
12. EXISTS
SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);

# 首先执行 外部查询 SELECT column_name(s) FROM table_name
# 将查询到的每一条数据传给内查询,看内查询能否查询到结果,查询不到返回Flase,反之为True
# 内查询返回为 True 则保留外查询这一条记录
13.SELECT TOP

​ 用于规定要返回的记录的数目,如果查询返回的结果很多,输出花费比较多,我们可以使用此语句来限定数目

# 适用于 SQL Server / MS Access
SELECT TOP number|percent column_name(s)
FROM table_name;
# 适用于 MySQL
SELECT column_name(s)
FROM table_name
LIMIT number;
# 适用于 Oracle
SELECT column_name(s)
FROM table_name
WHERE ROWNUM <= number;

select *
from Teach
limit 3;

6. 数据导出

# 导出数据
select * from table into outfile '路径';

# 导入数据
load data local infile '路径' into table 表名 fields terminated by ‘\t’

​ 在此之前,需要修改一下数据导出的默认路径

使用 show variables like '%secure%'; 查看secure-file-priv设置,
  			2. secure_file_prive=null ––限制mysqld 不允许导入导出
     secure_file_priv=/path/ – --限制mysqld的导入导出只能发生在默认的/path/目录下
     secure_file_priv=’’ – --不对mysqld 的导入 导出做限制
  			3. 在 mysql 的安转目录下找到 my.ini 文件,修改secure_file_prive 为 '' 使其不对mysqld 的导入 导出做限制
  			4. 打开计算机管理>>服务与应用程序>>服务>>mysql(版本不同名字可能不同)>>右键重新启动>>完成重启
  			5. 重复 1 步骤,看看修改是否成功,若没有成功可以试试重启电脑。
  			6. 之后再进行导入导出操作
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值