Artikelverzeichnis
- Grundkenntnisse in SQL
-
-
- 1. Einführung in die grundlegende SQL-Master-Anweisung
- 2. Grundlegende SQL-Anweisung
-
- 1. Erstellen Sie eine Datenbank
- 3. Backup-SQL-Server
- 4. Erstellen Sie eine neue Tabelle
- 5. Löschen Sie die neue Tabelle
- 6. Fügen Sie eine Spalte hinzu
- 7. Primärschlüssel hinzufügen
- 8. Erstellen Sie einen Index
- 9. Erstellen Sie eine Ansicht
- 10. Ändern Sie den Datenbanknamen
- 11. Ein paar einfache grundlegende SQL-Anweisungen
- 3. Erweiterte SQL-Anweisung
-
- 1. Mehrere erweiterte Abfrageoperatoren
- 2. Verbindungsabfrage
- 3. Gruppenabfrage
-
- 1. Grundlegende Grammatik
- 2. Grundlegende SQL-Nutzung
- 3. Verwendung des Gehäuses
-
- 1. Einzelfeldgruppierung
- 2. Gruppierung mehrerer Felder
- 3. Filtern Sie Daten vor dem Gruppieren
- 4. Filtern Sie Daten nach der Gruppierung
- 5. Sortieren Sie nach der Gruppierung
- 6. Wo & Gruppieren nach & Haben & Bestellen nach & Limit Arbeiten Sie zusammen
- 7. Es müssen mehrere Spalten angezeigt werden, und die Felder gehören nicht zur Gruppe
-
Grundkenntnisse in SQL
1. Einführung in die grundlegende SQL-Master-Anweisung
1. Die Schreibreihenfolge von mysql-Anweisungen
select
<要返回的数据列>
from
<表名>
<join, left join, right join...> join
<join表>
on
<join条件>
where
<where条件>
group by
<分组条件>
having
<分组后的筛选条件>
order by
<排序条件>
limit
<行数限制>
Jedoch
2. Die interne Ausführungsreihenfolge von mysql
from
<表名> # 笛卡尔积
on
<筛选条件> #对笛卡尔积的虚表进行筛选
<join, left join, right join...> join
<join表> #指定join,用于添加数据到on之后的虚表中,例如left join会将左表的剩余数据添加到虚表中
where
<where条件> #对上述虚表进行筛选
group by
<分组条件> #分组
<sum()等聚合函数> #用于having子句进行判断,在书写上这类聚合函数是写在having判断里面的
having
<分组筛选> #对分组后的结果进行聚合筛选
select
<返回数据列表> #返回的单列必须在group by子句中,聚合函数除外
distinct
order by
<排序条件> #排序
limit
<行数限制>
teilweise erklärt:
- from : select * from table_1, table_2; ist konsistent mit dem Ergebnis von select * from table_1 join table_2; beides bedeutet, das kartesische Produkt zu suchen;
Es wird verwendet, um das kartesische Produkt zweier Tabellen direkt zu berechnen, um die virtuelle Tabelle VT1 zu erhalten. Dies ist die erste Operation, die von allen select-Anweisungen ausgeführt wird. Andere Operationen werden an dieser Tabelle ausgeführt, die der Inhalt ist, der durch die from-Operation vervollständigt wird.
- on : Qualifizierte Daten aus der VT1-Tabelle filtern, um die VT2-Tabelle zu bilden;
- join : fügt die Daten dieses Join-Typs der VT2-Tabelle hinzu, zum Beispiel fügt left join die verbleibenden Daten der linken Tabelle zur virtuellen Tabelle VT2 hinzu, um eine VT3-Tabelle zu bilden; wenn die Anzahl der Tabellen größer als 2 ist, Schritte 1-3 werden wiederholt;
- wobei : Führen Sie das Screening aus (kann die Aggregationsfunktion nicht verwenden), um die VT4-Tabelle zu erhalten;
- group by : Gruppieren Sie die VT4-Tabelle, um die VT5-Tabelle zu erhalten; die Spalten, die in den nachfolgenden Verarbeitungsanweisungen verwendet werden, wie zum Beispiel select und having, müssen in der Bedingung group by enthalten sein, und Aggregatfunktionen müssen verwendet werden, wenn sie nicht erscheinen;
- Haben : Filtern Sie die gruppierten Daten, um die VT6-Tabelle zu erhalten;
- select : Spalte zurückgeben, um VT7-Tabelle zu erhalten;
- unique : wird zum Deduplizieren verwendet, um die VT8-Tabelle zu erhalten;
- order by : wird zum Sortieren verwendet, um die VT9-Tabelle zu erhalten;
- limit : geben Sie die erforderliche Anzahl von Zeilen zurück, erhalten Sie VT10;
2. Grundlegende SQL-Anweisung
1. Erstellen Sie eine Datenbank
CREATE DATABASE database-name
####2. Löschen Sie die Datenbank
drop database database-name
3. Backup-SQL-Server
--- 创建 备份数据的 device
USE master
EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'
--- 开始 备份
BACKUP DATABASE pubs TO testBack
4. Erstellen Sie eine neue Tabelle
create table tabname(col1 type1 [not null] [primary key],
col2 type2 [not null],
..)
--根据已有的表创建新表:
A:create table tab_new like tab_old (使用旧表创建新表)
B:create table tab_new as select col1,col2… from tab_old definition only
5. Löschen Sie die neue Tabelle
drop table tabname
6. Fügen Sie eine Spalte hinzu
Alter table tabname add column col type
--注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。
7. Primärschlüssel hinzufügen
Alter table tabname add primary key(col)
--说明:删除主键: Alter table tabname drop primary key(col)
8. Erstellen Sie einen Index
create [unique] index idxname on tabname(col….)
--删除索引:drop index idxname
9. Erstellen Sie eine Ansicht
create view viewname as select statement
--删除视图:drop view viewname
10. Ändern Sie den Datenbanknamen
sp_renamedb 'old_name', 'new_name'
11. Ein paar einfache grundlegende SQL-Anweisungen
选择:select * from table1 where 范围条件
插入:insert into table1(field1,field2) values(value1,value2)
删除:delete from table1 where 范围
更新:update table1 set field1=value1 where 范围
查找:select * from table1 where field1 like ’%value1%’ ---like的语法很精妙,查资料!
排序:select * from table1 order by field1,field2 [desc] --默认降序(大->小),[asc]升序
总数:select count(1) as totalcount from table1
求和:select sum(field1) as sumvalue from table1
平均:select avg(field1) as avgvalue from table1
最大:select max(field1) as maxvalue from table1
最小:select min(field1) as minvalue from table1
3. Erweiterte SQL-Anweisung
1. Mehrere erweiterte Abfrageoperatoren
A: UNION 运算符
UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。
示例:
-- A表和B表都有编号,名字两个字段,A表有10条数据,其中一条是(2,老段),B表有10条数据,其中一条是(2,老段),把两张表数据合起来的sql
select * from A UNION select * from B --(会有两条(2,老段)数据)
select * from A UNION ALL select * from B --(只有一条(2,老段)数据)
-- 一般只作为全连接查询使用
B: EXCEPT 运算符
EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。
C: INTERSECT 运算符
INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL 随 INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。
Hinweis: Mehrere Abfrageergebniszeilen, die Operationswörter für die oben genannten drei Schlüsselwörter verwenden, müssen konsistent sein.
2. Verbindungsabfrage
A、left (outer) join:
左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT JOIN b ON a.a = b.c
B:right (outer) join:
右外连接(右连接):结果集既包括连接表的匹配连接行,也包括右连接表的所有行。
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a RIGHT JOIN b ON a.a = b.c
C:full/cross (outer) join (oracle):
全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录,在mysql中可用UNION解决,不足的列补空
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT JOIN b ON a.a = b.c
UNION
select a.a, a.b, a.c, b.c, b.d, b.f from a RIGHT JOIN b ON a.a = b.c
D: inner join on
内连接查询:根据id条件查出来共有的部分
SQL: SELECT a.a, a.b, a.c, b.c, b.d, b.f FROM A INNER JOIN B ON a.c = b.c;
3. Gruppenabfrage
1. Grundlegende Grammatik
SELECT column, group_function,... FROM table
[WHERE condition]
GROUP BY group_by_expression
[HAVING group_condition];
veranschaulichen:
group_function: Aggregatfunktion.
group_by_expression: Gruppieren von Ausdrücken, getrennt durch Kommas.
group_condition: Filtern Sie die Daten nach der Gruppierung.
Beim Gruppieren kann es nach der Auswahl nur zwei Arten von Spalten geben:
- Spalten, die nach gruppieren nach erscheinen
- oder Spalten mit Aggregatfunktionen
aggregierte Funktion
Funktionsname | Wirkung |
---|---|
max | Abfrage des Maximalwerts der angegebenen Spalte |
Mindest | Fragt den Mindestwert der angegebenen Spalte ab |
zählen | Zählen Sie die Anzahl der Zeilen im Abfrageergebnis |
Summe | Sum, gibt die Summe der angegebenen Spalten zurück |
durchschn | Durchschnitt, gibt den Durchschnittswert der angegebenen Spaltendaten zurück |
2. Grundlegende SQL-Nutzung
select * from employee;
+------+------+--------+------+------+-------------+
| num | d_id | name | age | sex | homeaddr |
+------+------+--------+------+------+-------------+
| 1 | 1001 | 张三 | 26 | 男 | beijinghdq |
| 2 | 1002 | 李四 | 24 | 女 | beijingcpq |
| 3 | 1003 | 王五 | 25 | 男 | changshaylq |
| 4 | 1004 | Aric | 15 | 男 | England |
+------+------+--------+------+------+-------------+
select * from employee group by sex;
+------+------+--------+------+------+------------+
| num | d_id | name | age | sex | homeaddr |
+------+------+--------+------+------+------------+
| 2 | 1002 | 李四 | 24 | 女 | beijingcpq |
| 1 | 1001 | 张三 | 26 | 男 | beijinghdq |
+------+------+--------+------+------+------------+
根据sex字段来分组,sex字段的全部值只有两个('男'和'女'),所以分为了两组
当group by单独使用时,只显示出每组的第一条记录
所以group by单独使用时的实际意义不大
gruppieren nach + group_concat()
Verwenden Sie nach der Gruppierung gemäß den Gruppierungsergebnissen **group_concat()**, um eine Reihe von Werten eines Felds in jeder Gruppe zu platzieren
select sex from employee group by sex;
+------+
| sex |
+------+
| 女 |
| 男 |
+------+
select sex,group_concat(name) from employee group by sex;
+------+--------------------+
| sex | group_concat(name) |
+------+--------------------+
| 女 | 李四 |
| 男 | 张三,王五,Aric |
+------+--------------------+
select sex,group_concat(d_id) from employee group by sex;
+------+--------------------+
| sex | group_concat(d_id) |
+------+--------------------+
| 女 | 1002 |
| 男 | 1001,1003,1004 |
+------+--------------------+
Gruppieren nach + Aggregatfunktion
Inspiriert von **group_concat()**, da wir die Wertemenge eines Feldes in jeder Gruppe zählen können, können wir auch die set-Funktion verwenden, um einige Operationen an dieser "Wertemenge" durchzuführen.
select sex,group_concat(age) from employee group by sex;
+------+-------------------+
| sex | group_concat(age) |
+------+-------------------+
| 女 | 24 |
| 男 | 26,25,15 |
+------+-------------------+
分别统计性别为男/女的人年龄平均值
select sex,avg(age) from employee group by sex;
+------+----------+
| sex | avg(age) |
+------+----------+
| 女 | 24.0000 |
| 男 | 22.0000 |
+------+----------+
分别统计性别为男/女的人的个数
select sex,count(sex) from employee group by sex;
+------+------------+
| sex | count(sex) |
+------+------------+
| 女 | 1 |
| 男 | 3 |
+------+------------+
gruppieren nach + haben
(1) bedingter Ausdruck: Wird verwendet, um Abfragen zu gruppieren und einige Bedingungen für die Ausgabe von Abfrageergebnissen
anzugeben
select sex,count(sex) from employee group by sex having count(sex)>2;
+------+------------+
| sex | count(sex) |
+------+------------+
| 男 | 3 |
+------+------------+
Gruppieren nach + mit Rollup
Die Funktion von with rollup ist: Fügen Sie am Ende eine neue Zeile hinzu, um die Summe aller Datensätze in der aktuellen Spalte aufzuzeichnen
select sex,count(age) from employee group by sex with rollup;
+------+------------+
| sex | count(age) |
+------+------------+
| 女 | 1 |
| 男 | 3 |
| NULL | 4 |
+------+------------+
select sex,group_concat(age) from employee group by sex with rollup;
+------+-------------------+
| sex | group_concat(age) |
+------+-------------------+
| 女 | 24 |
| 男 | 26,25,15 |
| NULL | 24,26,25,15 |
+------+-------------------+
3. Verwendung des Gehäuses
Daten vorbereiten
drop table if exists t_order;
-- 创建订单表
create table t_order(
id int not null AUTO_INCREMENT COMMENT '订单id',
user_id bigint not null comment '下单人id',
user_name varchar(16) not null default '' comment '用户名',
price decimal(10,2) not null default 0 comment '订单金额',
the_year SMALLINT not null comment '订单创建年份',
PRIMARY KEY (id)
) comment '订单表';
-- 插入数据
insert into t_order(user_id,user_name,price,the_year) values
(1001,'路人甲Java',11.11,'2017'),
(1001,'路人甲Java',22.22,'2018'),
(1001,'路人甲Java',88.88,'2018'),
(1002,'刘德华',33.33,'2018'),
(1002,'刘德华',12.22,'2018'),
(1002,'刘德华',16.66,'2018'),
(1002,'刘德华',44.44,'2019'),
(1003,'张学友',55.55,'2018'),
(1003,'张学友',66.66,'2019');
mysql> select * from t_order;
+----+---------+---------------+-------+----------+
| id | user_id | user_name | price | the_year |
+----+---------+---------------+-------+----------+
| 1 | 1001 | 路人甲Java | 11.11 | 2017 |
| 2 | 1001 | 路人甲Java | 22.22 | 2018 |
| 3 | 1001 | 路人甲Java | 88.88 | 2018 |
| 4 | 1002 | 刘德华 | 33.33 | 2018 |
| 5 | 1002 | 刘德华 | 12.22 | 2018 |
| 6 | 1002 | 刘德华 | 16.66 | 2018 |
| 7 | 1002 | 刘德华 | 44.44 | 2019 |
| 8 | 1003 | 张学友 | 55.55 | 2018 |
| 9 | 1003 | 张学友 | 66.66 | 2019 |
+----+---------+---------------+-------+----------+
9 rows in set (0.00 sec)
1. Einzelfeldgruppierung
**Voraussetzung: **Anzahl der Bestellungen pro Benutzer abfragen, Ausgabe: Benutzer-ID, Bestellmenge, wie folgt:
mysql> SELECT
user_id 用户id, COUNT(id) 下单数量
FROM
t_order
GROUP BY user_id;
+----------+--------------+
| 用户id | 下单数量 |
+----------+--------------+
| 1001 | 3 |
| 1002 | 4 |
| 1003 | 2 |
+----------+--------------+
3 rows in set (0.00 sec)
2. Gruppierung mehrerer Felder
**Anforderung: **Abfrage der Anzahl der von jedem Benutzer pro Jahr aufgegebenen Bestellungen, die Ausgabefelder: Benutzer-ID, Jahr, Anzahl der Bestellungen, wie folgt:
mysql> SELECT
user_id 用户id, the_year 年份, COUNT(id) 下单数量
FROM
t_order
GROUP BY user_id , the_year;
+----------+--------+--------------+
| 用户id | 年份 | 下单数量 |
+----------+--------+--------------+
| 1001 | 2017 | 1 |
| 1001 | 2018 | 2 |
| 1002 | 2018 | 3 |
| 1002 | 2019 | 1 |
| 1003 | 2018 | 1 |
| 1003 | 2019 | 1 |
+----------+--------+--------------+
6 rows in set (0.00 sec)
3. Filtern Sie Daten vor dem Gruppieren
Um die Daten vor dem Gruppieren zu filtern, verwenden Sie das Schlüsselwort where
**Anforderung:**Muss die Anzahl der Bestellungen abfragen, die von jedem Benutzer im Jahr 2018 aufgegeben wurden, Ausgabe: Benutzer-ID, Bestellmenge, wie folgt:
mysql> SELECT
user_id 用户id, COUNT(id) 下单数量
FROM
t_order t
WHERE
t.the_year = 2018
GROUP BY user_id;
+----------+--------------+
| 用户id | 下单数量 |
+----------+--------------+
| 1001 | 2 |
| 1002 | 3 |
| 1003 | 1 |
+----------+--------------+
3 rows in set (0.00 sec)
4. Filtern Sie Daten nach der Gruppierung
Um Daten nach der Gruppierung zu filtern, verwenden Sie das Schlüsselwort „having“.
**Anforderung:** Benutzer abfragen, deren Bestellmenge im Jahr 2018 größer als 1 ist, Ausgabe: Benutzer-ID, Bestellmenge, wie folgt:
Methode 1:
mysql> SELECT
user_id 用户id, COUNT(id) 下单数量
FROM
t_order t
WHERE
t.the_year = 2018
GROUP BY user_id
HAVING count(id)>=2;
+----------+--------------+
| 用户id | 下单数量 |
+----------+--------------+
| 1001 | 2 |
| 1002 | 3 |
+----------+--------------+
2 rows in set (0.00 sec)
Methode 2:
mysql> SELECT
user_id 用户id, count(id) 下单数量
FROM
t_order t
WHERE
t.the_year = 2018
GROUP BY user_id
HAVING 下单数量>=2;
+----------+--------------+
| 用户id | 下单数量 |
+----------+--------------+
| 1001 | 2 |
| 1002 | 3 |
+----------+--------------+
2 rows in set (0.00 sec)
Der Unterschied zwischen wound haben
Wobei Datensätze vor der Gruppierung (Aggregation) gefiltert werden müssen, während die Ergebnisse nach der Gruppierung gefiltert und schließlich die Abfrageergebnisse des gesamten SQL zurückgegeben werden müssen.
Having kann als zweistufige Abfrage verstanden werden, d. h. die Abfrageoperation, die having enthält, ruft zuerst die Ergebnistabelle der SQL-Abfrage ohne die Having-Klausel ab, verwendet dann die Having-Bedingung für die Ergebnistabelle, um die übereinstimmenden Datensätze herauszufiltern, und kehrt schließlich zurück Auf diese Datensätze kann also nach have eine Aggregatfunktion folgen, und diese Aggregatfunktion muss nicht mit der Aggregatfunktion hinter select identisch sein.
5. Sortieren Sie nach der Gruppierung
Anforderung : Ermitteln Sie den Höchstbetrag jedes Benutzers und geben Sie dann in umgekehrter Reihenfolge des Höchstbetrags Folgendes aus: Benutzer-ID, Höchstbetrag:
mysql> SELECT
user_id 用户id, max(price) 最大金额
FROM
t_order t
GROUP BY user_id
ORDER BY 最大金额 desc;
+----------+--------------+
| 用户id | 最大金额 |
+----------+--------------+
| 1001 | 88.88 |
| 1003 | 66.66 |
| 1002 | 44.44 |
+----------+--------------+
3 rows in set (0.00 sec)
6. Wo & Gruppieren nach & Haben & Bestellen nach & Limit Arbeiten Sie zusammen
Bei gemeinsamer Verwendung von Schlüsselwörtern wie where, group by, having, order by und limit ist die Reihenfolge deutlich eingeschränkt, die Syntax lautet wie folgt:
select 列 from
表名
where [查询条件]
group by [分组表达式]
having [分组过滤条件]
order by [排序条件]
limit [offset,] count;
**Voraussetzung:** Anzahl der getätigten Bestellungen größer oder gleich 2 im Jahr 2018 abfragen, nach Anzahl der getätigten Bestellungen absteigend sortieren und schließlich nur den ersten Datensatz ausgeben mit Anzeige von: Benutzer-ID, Bestellmenge, als folgt:
mysql> SELECT
user_id 用户id, COUNT(id) 下单数量
FROM
t_order t
WHERE
t.the_year = 2018
GROUP BY user_id
HAVING count(id)>=2
ORDER BY 下单数量 DESC
LIMIT 1;
+----------+--------------+
| 用户id | 下单数量 |
+----------+--------------+
| 1002 | 3 |
+----------+--------------+
1 row in set (0.00 sec)
7. Es müssen mehrere Spalten angezeigt werden, und die Felder gehören nicht zur Gruppe
Anforderung: Holen Sie sich den maximalen Betrag der Bestellung jedes Benutzers und das Jahr der Bestellung, Ausgabe: Benutzer-ID, maximaler Betrag, Jahr
Zwei Schreibweisen:
mysql> SELECT
user_id 用户id,
price 最大金额,
the_year 年份
FROM
t_order t1
WHERE
(t1.user_id , t1.price)
IN
(SELECT
t.user_id, MAX(t.price)
FROM
t_order t
GROUP BY t.user_id);
+----------+--------------+--------+
| 用户id | 最大金额 | 年份 |
+----------+--------------+--------+
| 1001 | 88.88 | 2018 |
| 1002 | 44.44 | 2019 |
| 1003 | 66.66 | 2019 |
+----------+--------------+--------+
3 rows in set (0.00 sec)
mysql> SELECT
user_id 用户id,
price 最大金额,
the_year 年份
FROM
t_order t1,(SELECT
t.user_id uid, MAX(t.price) pc
FROM
t_order t
GROUP BY t.user_id) t2
WHERE
t1.user_id = t2.uid
AND t1.price = t2.pc;
+----------+--------------+--------+
| 用户id | 最大金额 | 年份 |
+----------+--------------+--------+
| 1001 | 88.88 | 2018 |
| 1002 | 44.44 | 2019 |
| 1003 | 66.66 | 2019 |
+----------+--------------+--------+
3 rows in set (0.00 sec)
上面第1种写法,比较少见,in中使用了多字段查询
Vorschlag: Schreiben Sie eine Gruppenabfrage am besten nach der Standardvorgabe: Die Spalten, die nach dem select erscheinen, müssen in der group by sein oder die Aggregatfunktion verwenden.