第 1 章 SQL の概要
1.1 SQLとは何ですか
- SQL: 構造クエリ言語。(構造化クエリ言語)、SQLによるデータベースの操作(操作データベース、操作テーブル、操作データ)
- SQL は、米国標準協会 (ANSI) によってリレーショナル データベース言語の米国標準として認定され、その後、国際標準化機構 (ISO) によってリレーショナル データベース言語の国際標準として採用されました。
- すべてのデータベース ベンダー (MySql、oracle、SQL サーバー) は ISO SQL 標準をサポートしています。
- 各データベース ベンダーは、標準に基づいて独自の拡張機能を作成しています。各データベースには独自の固有の構文があります
1.2 SQLの分類
- データ定義言語 (DDL データ定義言語) など: オペレーティング データベース、オペレーティング テーブル
- データ操作言語(DML データ操作言語)。テーブル内のレコードの追加、削除、変更など。
- データ クエリ言語(DQL データ クエリ言語)、たとえば: テーブル内のデータに対するクエリ操作
- データ制御言語 (DCL データ制御言語)、たとえば: ユーザー権限の設定
1.3 MySQL 構文の仕様と要件
(1) mysql の SQL 構文は大文字と小文字を区別しません。
MySQL のキーワードと関数名は大文字と小文字を区別しませんが、データ値が大文字と小文字を区別するかどうかは文字セットと照合規則に関係します。
ci (大文字と小文字を区別しない)、cs (大文字と小文字を区別する)、_bin (バイナリ。つまり、比較は文字エンコーディングの値に基づいており、言語とは関係ありません。大文字と小文字が区別されます)
(2) 名前を付けるとき: 26 文字の英字の大文字と小文字、数字 0 ~ 9、アンダースコアを使用し、他の記号は使用しないでください。
(3) mysql キーワードをテーブル名、フィールド名などに使用しないことをお勧めします。誤って使用した場合は、SQL 文中に ` (浮動記号) を使用してください。
(4) データベース名やテーブル名、フィールド名などのオブジェクト名の間にはスペースを入れないでください。
(5) 同じ mysql ソフトウェア内でデータベースに同じ名前を付けることはできません。同じライブラリ内でテーブルに同じ名前を付けることはできません。また、同じテーブル内でフィールドに同じ名前を付けることはできません。
(6) 句読点:
ペアでなければなりません
下半角の入力方法は英語でなければなりません
文字列型と日付型では一重引用符を使用できます ''
列の別名には二重引用符 "" を使用できますが、テーブル名の別名には二重引用符を使用しないでください。エイリアスを取得する場合は省略できます
列のエイリアスにスペースが含まれていない場合は二重引用符を省略できますが、スペースが含まれている場合は二重引用符を省略できません。
(7) SQLスクリプトにコメントを追加する方法
単一行コメント: #comment content
単一行のコメント: – スペース コメントの内容 – 後ろのスペースは次のとおりです。
複数行コメント: /* コメント内容 */
#以下两句是一样的,不区分大小写
show databases;
SHOW DATABASES;
#创建表格
#create table student info(...); #表名错误,因为表名有空格
create table student_info(...);
#其中name使用``飘号,因为name和系统关键字或系统函数名等预定义标识符重名了。
CREATE TABLE t_stu(
id INT,
`name` VARCHAR(20)
);
select id as "编号", `name` as "姓名" from t_stu; #起别名时,as都可以省略
select id as 编号, `name` as 姓名 from t_stu; #如果字段别名中没有空格,那么可以省略""
select id as 编 号, `name` as 姓 名 from t_stu; #错误,如果字段别名中有空格,那么不能省略""
第 2 章 - DDL 操作データベース
2.1 データベース(マスター)の作成
- 文法
create database 数据库名 [character set 字符集][collate 校对规则] 注: []意思是可选的意思
文字セット (charset): 記号とエンコーディングのセットです。
- 練習する
day01 (デフォルトの文字セット) のデータベースを作成します。
create database day01;
day01_2 データベースを作成し、文字セットを gbk (理解) として指定します。
create database day01_2 character set gbk;
2.2 すべてのデータベースを表示する
2.2.1 すべてのデータベースを表示する
- 文法
show databases;
2.2.2 データベースの定義構造を見る【理解する】
- 文法
show create database 数据库名;
- データベース day01 の定義を表示する
show create database day01;
2.3 データベースを削除する
- 文法
drop database 数据库名;
- day01_2 データベースを削除します
drop database day01_2;
2.4 データベースの変更【理解】
- 文法
alter database 数据库名 character set 字符集;
- day01のデータベースの文字セット(gbk)を変更する
alter database day01 character set gbk;
知らせ:
- utf-8ではなくutf8です
- データベース名を変更しないでください
2.5 その他の操作
- データベースを切り替え、どのデータベースを選択するか
use 数据库名; //注意: 在创建表之前一定要指定数据库. use 数据库名
- 演習: day01 を使用します。
use day01;
- 使用中のデータベースを確認する
select database();
第 3 章 - DDL 操作テーブル
3.1 テーブルの作成
3.1.1 構文
create table 表名(
列名 类型 [约束],
列名 类型 [约束]
...
);
3.1.2 タイプ
3.1.2.1 数値型
- 整数系列: xxxInt
int(M)、意味を持たせるためには符号なしゼロフィルとともに使用する必要があります
- 浮動小数点系列: float、double (または real)
double(M,D): 最長が M 桁で、そのうち小数点以下 D 桁であることを示します。
例: double(5,2) [-999.99,999.99] で表されるデータ範囲。この範囲を超えるとエラーが報告されます。
- 固定小数点系列: 10 進数 (最下層は実際には文字列を使用して格納されます)
10進数(M,D): 最長がM桁で、そのうち小数点以下がD桁であることを示します。
- ビットタイプ: ビット
バイト範囲は 1 ~ 8、値の範囲は bit(1) ~ bit(64)、デフォルトの bit(1) です。
2 進数を格納するために使用されます。ビット フィールドの場合、select コマンドを直接使用しても結果は表示されません。bit() 関数または hex() 関数を使用して読み取ることができます。ビット型のフィールドを挿入する場合、バイナリコードは「01」となるため、bit()関数を使用してバイナリ値に変換して挿入してください。
3.1.2.2 日時型
日付時刻タイプ: 年、日付、日時、タイムスタンプ
各日時の表現範囲に注意
タイムスタンプと日時の違い:
- タイムスタンプの範囲は比較的狭いです
- タイムスタンプはタイムゾーンに関連しています
- 「time_zone」のような変数を表示します。
- タイムゾーンを設定 = '+8:00';
- タイムスタンプはサーバーの MySQL バージョンと SQLMode に大きく影響されます。
- テーブル内の空ではない最初のタイムスタンプ フィールドが挿入され、NULL として更新されると、自動的にシステム時刻に設定されます。
3.1.2.3 文字列型
MySQL は文字データ用にさまざまなストレージ タイプを提供しており、バージョンが異なると異なる場合があります。一般的なものは次のとおりです。
char、varchar、xxtext、バイナリ、varbinary、xxblob、enum、set など。
- 文字列型 char、varchar(M)
char 幅が指定されていない場合、デフォルトは 1 文字です
varchar(M)、幅を指定する必要があります
-
binary と varbinary は、バイナリ文字列を含み、ファジー クエリなどをサポートしない点を除けば、char と varchar に似ています。
-
一般に、少数の文字列を保存する場合は char と varchar を選択し、大きなテキストを保存する場合は通常 text または blob シリーズの使用を選択します。BLOB およびテキスト値はパフォーマンス上の問題を引き起こし、特に多数の削除操作が実行されると、データ テーブルに大きな「穴」が残ります。パフォーマンスを向上させるには、最適化を使用することをお勧めします。このようなテーブルに対してテーブル関数を使用して、定期的にデフラグを実行します。合成 (合成) インデックスを使用すると、大きなテキスト フィールドのクエリ パフォーマンスを向上させることができます。大きなテキスト フィールドに対してファジー クエリを実行する必要がある場合、MySql はプレフィックス インデックスを提供します。ただし、必要でない場合は、大きな BLOB またはテキスト値を取得することは避けてください。
-
enum 列挙型の場合、その値の範囲はテーブルの作成時に列挙によって明示的に指定する必要があります。1 ~ 255 メンバーの列挙の場合、1 バイトのストレージが必要です。255`65535 メンバーの場合、2 バイトのストレージが必要です。例: 性別 enum('男','女')。列挙値以外の値が挿入された場合は、最初の値として処理されます。一度に選択できる列挙値は 1 つだけです。
-
セット コレクション タイプには 0 ~ 64 のメンバーを含めることができます。セットから一度に複数のメンバーを選択できます。1 ~ 8 のメンバーのセットが選択された場合、順番に 1 バイト、2、3 が占有されます。。8バイト。例: hoppy set('eating','sleeping','playing games','traveling')、「食事、睡眠」または「睡眠、ゲーム、旅行」を選択した場合
3.1.2.4 例
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| eid | int(11) | NO | PRI | NULL | auto_increment |
| ename | varchar(20) | NO | | NULL | |
| tel | char(11) | NO | | NULL | |
| gender | char(1) | YES | | 男 | |
| salary | double | YES | | NULL | |
| commission_pct | double(3,2) | YES | | NULL | |
| birthday | date | YES | | NULL | |
| hiredate | date | YES | | NULL | |
| job_id | int(11) | YES | | NULL | |
| email | varchar(32) | YES | | NULL | |
| mid | int(11) | YES | | NULL | |
| address | varchar(150) | YES | | NULL | |
| native_place | varchar(10) | YES | | NULL | |
| did | int(11) | YES | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
3.1.3 制約
- つまり、規則、規則、規制です。
- 役割: ユーザーが挿入したデータが仕様に従ってデータベースに保存されるようにする
制約 | 制約キーワード | |
---|---|---|
主キー | 主キー | 空ではなく一意であり、テーブルには主キーを 1 つだけ持つことができます。 |
のみ | 個性的 | 一意であり、同じデータを現在の列に表示することはできません |
空ではない | nullではない | 空ではありません。現在の列を null にすることはできません |
デフォルト | デフォルト | 現在の列にデータがない場合のデフォルトのデータを指定します |
制約タイプ:
-
not null: 空ではない; 例: username varchar(40) not null username この列には null 値を含めることはできません
-
unique: 一意の制約、次のデータを前のデータと繰り返すことはできません; 例: CardNo char(18) unique; CardNo 列に重複するデータはありません
-
主キー; 主キー制約 (空ではない + 一意); 通常、テーブルの id 列で使用されます。テーブルには基本的に id 列があり、id 列は一意の識別子として使用されます。
- auto_increment:自動拡張。auto_increment を使用する前に主キーを設定する必要があります。
-
id int プライマリキー auto_increment; id は自分で管理する必要はなく、データを挿入する場合は null を直接挿入し、重複を避けるために自動的に拡張および埋められます。
知らせ:
- 最初に主キーを設定し、次に auto_increment を設定します。
- null は auto_increment が設定されている場合にのみ挿入できます。それ以外の場合は、null の挿入時にエラーが報告されます。
id列:
- idをint型に設定し、主キー制約を追加し、自動拡張する
- または、ID を文字列型に設定し、主キー制約を追加し、自動拡張を設定できません
3.1.4 演習
- Student テーブルを作成します (ID フィールドを使用します。名前フィールドは繰り返すことができません。性別フィールドは空にすることはできません。デフォルト値は男性で、ID の主キーは自動的に増加します)。
CREATE TABLE student(
id INT PRIMARY KEY AUTO_INCREMENT, -- 主键自增长
NAME VARCHAR(30) UNIQUE, -- 唯一约束
gender CHAR(1) NOT NULL DEFAULT '男'
);
3.2 表を確認する[理解する]
3.2.1 すべてのテーブルを表示する
show tables;
3.2.2 テーブルの定義構造を見る
-
文法
記述テーブル名。
-
演習: Student テーブルの定義構造を表示する
desc student;
3.3 テーブルの修正【マスターするけど覚えない】
3.3.1 文法
- 列を追加する
alter table 【数据库名.]表名称 add 【column】 字段名 数据类型;
alter table 【数据库名.]表名称 add 【column】 字段名 数据类型 first;
alter table 【数据库名.]表名称 add 【column】 字段名 数据类型 after 另一个字段;
- 列の型制約を変更します。
alter table 表名 modify 字段 类型 约束 ;
- 列名、型、制約を変更します。
alter table 表名 change 旧列 新列 类型 约束;
- 列を削除します。
alter table 表名 drop 列名;
- テーブル名を変更します。
rename table 旧表名 to 新表名;
3.3.2 演習
- 学生テーブルに成績フィールドを追加します。タイプは varchar(20) で、空にすることはできません。
ALTER TABLE student ADD grade VARCHAR(20) NOT NULL;
- Student テーブルの性別フィールドを int 型に変更します。空にすることはできません。デフォルト値は 1 です。
alter table student modify gender varchar(20);
- Student テーブルの Grade フィールドを Class フィールドに変更します
ALTER TABLE student CHANGE grade class VARCHAR(20) NOT NULL;
- クラスフィールドを削除する
ALTER TABLE student DROP class;
- 生徒テーブルを教師テーブルに変更(理解)
RENAME TABLE student TO teacher;
3.4 テーブルの削除【マスター】
-
文法
テーブルテーブル名をドロップします。
-
教師テーブルを削除する
drop table teacher;
第4章 DML操作テーブルのレコードの追加・削除・変更 【ポイント】
- 準備:商品テーブル(商品ID、商品名、商品価格、商品数量)を作成します。
create table product(
pid int primary key auto_increment,
pname varchar(40),
price double,
num int
);
4.1 レコードの挿入
4.1.1 構文
-
方法 1: 指定した列を挿入します。列がリストされていない場合は、自動的に null が割り当てられます。
例: pname、price、insert into t_product(pname,price)、values('mac',18000); を挿入したいだけです。
insert into 表名(列,列..) values(值,值..);
注: 列が挿入されず、非 null 制約が設定されている場合、エラーが報告されます。
- 方法 2: すべての列を挿入します。列に値を挿入したくない場合は、null の値を割り当てる必要があります。
insert into 表名 values(值,值....);
eg:
insert into product values(null,'苹果电脑',18000.0,10);
insert into product values(null,'华为5G手机',30000,20);
insert into product values(null,'小米手机',1800,30);
insert into product values(null,'iPhonex',8000,10);
insert into product values(null,'iPhone7',6000,200);
insert into product values(null,'iPhone6s',4000,1000);
insert into product values(null,'iPhone6',3500,100);
insert into product values(null,'iPhone5s',3000,100);
insert into product values(null,'方便面',4.5,1000);
insert into product values(null,'咖啡',11,200);
insert into product values(null,'矿泉水',3,500);
4.2 記録の更新
4.2.1 文法
update 表名 set 列 =值, 列 =值 [where 条件]
4.2.2 演習
- 全商品の価格を5000元に変更します
update product set price = 5000;
- 製品名をApple Computerに変更し、価格を18,000元に変更
UPDATE product set price = 18000 WHERE pname = '苹果电脑';
- 製品名を Apple Computer に変更し、価格を 17000 に変更し、数量を 5 に変更します。
UPDATE product set price = 17000,num = 5 WHERE pname = '苹果电脑';
- 商品名がインスタントラーメンの商品の価格を本来の価格から2元値上げする
UPDATE product set price = price+2 WHERE pname = '方便面';
4.3 レコードの削除
4.3.1 削除
条件に応じてデータを1つずつ削除します
- 文法
delete from 表名 [where 条件] 注意: 删除数据用delete,不用truncate
- タイプ
テーブル内の「Apple Computer」という名前のレコードを削除します。
delete from product where pname = '苹果电脑';
価格が5001未満の商品レコードを削除します
delete from product where price < 5001;
テーブル内のすべてのレコードを削除します (通常、削除に delete ステートメントを使用することは推奨されません。delete ステートメントは 1 行ずつ実行され、速度が遅すぎます)。
delete from product;
4.3.2 切り捨て
テーブルを直接 DROP して、同じ新しいテーブルを作成します。削除されたデータは復元できません。DELETEよりも高速に実行されます
truncate table 表;
4.3.3 作業中のデータ削除
- 物理的な削除: 実際には削除されますが、データは存在しません。削除の使用は物理的な削除です。
- 論理的な削除: 実際の削除はありません。データはまだそこにあります。マークを付けます。実際、論理的な削除は更新です。例: 状態 1 有効 0 無効
第5章 - DQL演算テーブルレコード - クエリ【ポイント】
5.1 基本的なクエリ構文
select 要查询的字段名 from 表名 [where 条件]
5.2 単純なクエリ
5.2.1 すべての行と列のレコードのクエリ
- 文法
select * form 表
- 製品テーブル内のすべての列をクエリします。
select * from product;
5.2.2 テーブル内の特定の列のレコードをクエリする
- 文法
select 列名,列名,列名... from 表
- 製品名と価格を問い合わせる
select pname, price from product;
5.2.3 個別の重複排除クエリ
- 文法
SELECT DISTINCT 字段名 FROM 表名; //要数据一模一样才能去重
- クエリ製品の名前の重複を排除します。
SELECT DISTINCT pname,price FROM product
注: 重複排除は特定の列を対象としているため、列名を個別の列の前に指定することはできません。
5.2.4 エイリアスクエリ
- 文法
select 列名 as 别名 ,列名 from 表 //列别名 as可以不写
select 别名.* from 表 as 别名 //表别名(多表查询, 明天会具体讲)
- 製品情報をクエリするには、エイリアスを使用します
SELECT pid ,pname AS '商品名',price AS '商品价格',num AS '商品库存' FROM product
5.2.5 演算クエリ(+、-、*、/、%など)
- 製品名と製品価格 +10 をクエリ: 特定のフィールドに固定値を追加し、複数のフィールドに対して計算クエリを実行できます。
select pname ,price+10 as 'price' from product;
select name,chinese+math+english as total from student
知らせ
- 操作クエリフィールド、フィールド間の操作が可能
- 文字列などの型は操作クエリに使用できますが、結果は無意味です
5.3 条件付きクエリ (非常に重要)
5.3.1 構文
select ... from 表 where 条件
//取出表中的每条数据,满足条件的记录就返回,不满足条件的记录不返回
5.3.2 演算子
1. 比較演算子
大于:>
小于:<
大于等于:>=
小于等于:<=
等于:= 不能用于null判断
不等于:!= 或 <>
安全等于: <=> 可以用于null值判断
2. 論理演算子 (読みやすさの観点から、単語の使用を推奨します)
逻辑与:&& 或 and
逻辑或:|| 或 or
逻辑非:! 或 not
逻辑异或:^ 或 xor
3. 範囲
区间范围:between x and y
not between x and y
集合范围:in (x,x,x)
not in (x,x,x)
4.あいまい検索と正規一致(文字列型、日付型のみ)
like 'xxx' 模糊查询是处理字符串的时候进行部分匹配
如果想要表示0~n个字符,用%
如果想要表示确定的1个字符,用_
regexp '正则'
5. 特別な null 値の処理
#(1)判断时
xx is null
xx is not null
xx <=> null
#(2)计算时
ifnull(xx,代替值) 当xx是null时,用代替值计算
5.3.3 演習
- 価格が 3000 を超える製品をクエリする
select * from product where price > 3000;
- pid=1 で製品をクエリします
select * from product where pid = 1;
- pid<>1 (!=) を使用して製品をクエリします。
select * from product where pid <> 1;
- 価格が 3000 ~ 6000 の製品のクエリ
select * from product where price between 3000 and 6000;
- pid が 1、5、7、15 の範囲にある製品をクエリします
select * from product where id = 1;
select * from product where id = 5;
select * from product where id = 7;
select * from product where id = 15;
select * from product where id in (1,5,7,15);
- 製品名が iPho で始まる製品の問い合わせ(iPhone シリーズ)
select * from product where pname like 'iPho%';
- 価格が 3000 を超え、数量が 20 を超えるアイテムをクエリします (条件と条件と...)
select * from product where price > 3000 and num > 20;
- ID=1 または価格が 3000 未満のアイテムをクエリします
select * from product where pid = 1 or price < 3000;
5.4 クエリの並べ替え
並べ替えはクエリの後に書き込まれます。つまり、データがクエリされてから並べ替えられます。
5.4.1 環境の準備
# 创建学生表(有sid,学生姓名,学生性别,学生年龄,分数列,其中sid为主键自动增长)
CREATE TABLE student(
sid INT PRIMARY KEY auto_increment,
sname VARCHAR(40),
sex VARCHAR(10),
age INT,
score DOUBLE
);
INSERT INTO student VALUES(null,'zs','男',18,98.5);
INSERT INTO student VALUES(null,'ls','女',18,96.5);
INSERT INTO student VALUES(null,'ww','男',15,50.5);
INSERT INTO student VALUES(null,'zl','女',20,98.5);
INSERT INTO student VALUES(null,'tq','男',18,60.5);
INSERT INTO student VALUES(null,'wb','男',38,98.5);
INSERT INTO student VALUES(null,'小丽','男',18,100);
INSERT INTO student VALUES(null,'小红','女',28,28);
INSERT INTO student VALUES(null,'小强','男',21,95);
5.4.2 単一列のソート
- 構文: 特定のフィールドのみで並べ替え、単一の列で並べ替え
SELECT 字段名 FROM 表名 [WHERE 条件] ORDER BY 字段名 [ASC|DESC]; //ASC: 升序,默认值; DESC: 降序
- ケース: すべての生徒をスコアの降順でクエリします。
SELECT * FROM student ORDER BY score DESC
5.4.3 組み合わせソート
- 構文: 複数のフィールドを同時に並べ替えます。最初のフィールドが等しい場合は、2 番目のフィールドで並べ替えます。
SELECT 字段名 FROM 表名 WHERE 字段=值 ORDER BY 字段名1 [ASC|DESC], 字段名2 [ASC|DESC];
- 演習: すべての生徒をスコアの降順でクエリし、スコアが同じ場合は年齢の降順でクエリします。
SELECT * FROM student ORDER BY score DESC, age DESC
5.5 集計関数
集計関数は統計に使用され、通常はグループ化クエリと一緒に使用され、各グループのデータをカウントします。
5.5.1 集計関数の一覧
集計関数 | 効果 |
---|---|
max(列名) | この列の最大値を見つけます |
min(列名) | この列の最小値を見つけます |
avg(列名) | この列の平均を求めます |
count(列名) | この列にレコードが何件あるかを数えます |
sum(列名) | この列を合計します |
- 文法
SELECT 聚合函数(列名) FROM 表名 [where 条件];
- ケース
-- 求出学生表里面的最高分数
SELECT MAX(score) FROM student
-- 求出学生表里面的最低分数
SELECT MIN(score) FROM student
-- 求出学生表里面的分数的总和(忽略null值)
SELECT SUM(score) FROM student
-- 求出学生表里面的平均分
SELECT AVG(score) FROM student
-- 求出学生表里面的平均分(缺考了当成0分处理)
SELECT AVG(IFNULL(score,0)) FROM student
-- 统计学生的总人数 (忽略null)
SELECT COUNT(sid) FROM student
SELECT COUNT(*) FROM student
注: 集計関数は NULL 値を無視します。
NULL レコードはカウントされないことがわかりました。数がカウントされる場合は NULL になる可能性がある列を使用しないことをお勧めしますが、NULL をカウントする必要がある場合はどうすればよいでしょうか? この問題は、IFNULL(列名, デフォルト値) 関数で解決できます。列が null でない場合は、この列の値を返します。NULL の場合、デフォルト値が返されます。
-- 求出学生表里面的平均分(缺考了当成0分处理)
SELECT AVG(IFNULL(score,0)) FROM student;
5.6 グループクエリ
GROUP BY は、グループ化フィールドの結果の同じ内容をグループとして扱い、各グループの最初のデータを返すため、グループ化だけでは役に立ちません。グループ化の目的は統計です。通常、グループ化は集計関数と併用されます。
5.6.1 グループ化
- 文法
SELECT 字段1,字段2... FROM 表名 [where 条件] GROUP BY 列 [HAVING 条件];
- ケース
-- 根据性别分组, 统计每一组学生的总人数
SELECT sex '性别',COUNT(sid) '总人数' FROM student GROUP BY sex
-- 根据性别分组,统计每组学生的平均分
SELECT sex '性别',AVG(score) '平均分' FROM student GROUP BY sex
-- 根据性别分组,统计每组学生的总分
SELECT sex '性别',SUM(score) '总分' FROM student GROUP BY sex
5.6.2 グループ化後のフィルタ
where の後にグループ化後の条件を記述することはできません。where キーワードは group by の前に記述する必要があります。
- 性別のグループ分けに従って、各グループの生徒の合計数を数えます > 5 (グループ分け後のスクリーニング)
SELECT sex, count(*) FROM student GROUP BY sex HAVING count(sid) > 5
- 性別グループ分けによると、年齢のみが 18 歳以上であり、グループ内の人数は 4 人以上である必要があります
SELECT sex '性别',COUNT(sid) '总人数' FROM student WHERE age >= 18 GROUP BY sex HAVING COUNT(sid) > 4
5.6.3 [面接] を行う場合と行う場合の違い
子名 | 効果 |
---|---|
where 子句 | 1) クエリ結果をグループ化する前に、where 条件を満たさない行を削除します。つまり、グループ化する前にデータをフィルタリングします。つまり、最初にフィルタリングしてからグループ化します。2) where の後には集計関数を使用できません |
有権節 | 1) Hasting 句の機能は、条件を満たすグループをフィルタリングすることです。つまり、グループ化した後にデータをフィルタリングします。つまり、最初にグループ化してからフィルタリングします。2) 集計関数は、 |
5.7 ページネーションクエリ
5.7.1 構文
select ... from .... limit a ,b
限界a、b; |
---|
aはスキップされたデータの数を表します |
b はクエリされるデータの数を表します |
5.7.2 ケース
-- 分页查询
-- limit 关键字是使用在查询的后边,如果有排序的话则使用在排序的后边
-- limit的语法: limit offset,length 其中offset表示跳过多少条数据,length表示查询多少条数据
SELECT * FROM product LIMIT 0,3
-- 查询product表中的前三条数据(0表示跳过0条,3表示查询3条)
SELECT * FROM product LIMIT 3,3
-- 查询product表的第四到六条数据(3表示跳过3条,3表示查询3条)
-- 分页的时候,只会告诉你我需要第几页的数据,并且每页有多少条数据
-- 假如,每页需要3条数据,我想要第一页数据: limit 0,3
-- 假如,每页需要3条数据,我想要第二页数据: limit 3,3
-- 假如,每页需要3条数据,我想要第三页数据: limit 6,3
-- 结论: length = 每页的数据条数,offset = (当前页数 - 1)*每页数据条数
-- limit (当前页数 - 1)*每页数据条数, 每页数据条数
5.8 クエリの構文の概要
select...from...where...group by...order by...limit
select...from...where...
select...from...where...order by...
select...from...where...limit...
select...from...where...order by...imit
第 6 章 データベースの 3 つのパラダイム
優れたデータベース設計は、データ ストレージのパフォーマンスとその後のプログラム開発に重要な影響を与えます。科学的で標準化されたデータベースを確立するには、データの設計と保存を最適化するためのいくつかのルールを満たす必要があります。これらのルールはパラダイムと呼ばれます。
6.1 第一正規形:各列がアトミックであることを保証する
第一正規形は最も基本的な正規形です。データベーステーブル内のすべてのフィールド値が分解不可能な原子値である場合、データベーステーブルが第一正規形を満たすことを意味します。
第一正規形の合理的な準拠は、システムの実際のニーズに従って決定する必要があります。例えば、一部のデータベースシステムでは「アドレス」属性を使用する必要がありますが、本来は「アドレス」属性をデータベーステーブルのフィールドとして直接設計する必要があります。ただし、システムが「住所」属性の「市」部分に頻繁にアクセスする場合は、「住所」属性を州、市、詳細な住所などの複数の部分に再分割して保存する必要があり、非常に便利になります。一部の操作用。この方法でのみ、次の表に示すように、設計がデータベースの第 1 正規形を満たすことができます。
第一正規形に従っていない場合、クエリ データはさらに処理する必要があります (クエリは不便です)。第一正規形に準拠し、フィールド データを必要とするデータをクエリします (クエリが簡単)
6.2 第 2 正規形:テーブル内のすべての列が主キーに関連付けられていることを確認してください
第 2 正規形は、第 1 正規形に基づくさらなる層です。第 2 正規形では、データベース テーブルの各列が、主キーの特定の部分 (主に結合主キー) だけでなく、主キーに関連付けられていることを確認する必要があります。つまり、データベース テーブルでは、1 つのテーブルに 1 種類のデータのみを格納でき、複数の種類のデータを同じデータベース テーブルに格納することはできません。
たとえば、注文情報テーブルを設計する場合、注文には多くの種類の商品が含まれる可能性があるため、次のようにデータベース テーブルの結合主キーとして注文番号と製品番号を使用する必要があります。テーブル
これにより問題が発生します。このテーブルでは、注文番号と製品番号が結合主キーとして使用されます。このように、テーブル内の商品名、単位、商品価格などの情報は、テーブルの主キーには関連付けられず、商品番号のみに関連付けられます。したがって、ここでは第 2 正規形の設計原則に違反します。
そして注文情報テーブルを分割し、商品情報も別テーブルに分け、注文品目テーブルも別テーブルに分ければ完璧です。次のように
<img src="imgs/tu_13.png" style="zoom: 67%;" />
この設計により、データベースの冗長性が大幅に軽減されます。注文の製品情報を取得したい場合は、製品番号を使用して製品情報テーブルをクエリします。
6.3 第 3 正規形:各列が主キー列に間接的ではなく直接関連していることを確認します。
第 3 正規形では、データ テーブル内のデータの各列が主キーに間接的ではなく直接関連付けられていることを確認する必要があります。
たとえば、注文データ テーブルを設計する場合、顧客番号を外部キーとして使用して、注文テーブルとの対応関係を確立できます。他の顧客情報 (名前、会社など) に関するフィールドを注文テーブルに追加することはできません。次の 2 つの表に示されている設計は、第 3 正規形を満たすデータベース テーブルです。
<img src="imgs/tu_14.png" style="zoom:67%;" />
これにより、注文情報を問い合わせる際に、顧客番号を利用して顧客情報テーブルのレコードを参照することができ、注文情報テーブルに顧客情報の内容を何度も入力する必要がなくなり、データの重複が軽減されます。
第 7 章 外部キー制約
7.1 外部キー制約の概念
3 つのパラダイムに従うことを前提として、冗長データを減らすためにテーブルを分割し、複数のテーブルにデータを格納する必要があることがよくあります。ただし、分割されたテーブルとテーブルの間には関連付けられた関係があります。テーブル間の関係を合意するには制約を使用する必要があります。この制約が外部キー制約です。
7.2 外部キー制約の役割
外部キー制約は、1 つまたは 2 つのテーブル間の参照整合性を保証するもので、外部キーは、1 つのテーブルの 2 つのフィールド、または 2 つのテーブルの 2 つのフィールド間の参照関係です。
7.3 外部キー制約を作成するための構文
7.3.1 テーブル作成時の外部キー制約の指定
create table [数据名.]从表名(
字段名1 数据类型 primary key ,
字段名2 数据类型 ,
....,
[constraint 外键约束名] foreign key (从表字段) references 主表名(主表字段) [on update 外键约束等级][on delete 外键约束等级]
#外键只能在所有字段列表后面单独指定
#如果要自己命名外键约束名,建议 主表名_从表名_关联字段名_fk
);
7.8.2 テーブル作成後の外部キー制約の指定
alter table 从表名称 add [constraint 外键约束名] foreign key (从表字段名) references 主表名(主表被参照字段名) [on update xx][on delete xx];
7.4 外部キー制約を削除するための構文
ALTER TABLE 表名称 DROP FOREIGN KEY 外键约束名;
#查看约束名 SELECT * FROM information_schema.table_constraints WHERE table_name = '表名称';
#删除外键约束不会删除对应的索引,如果需要删除索引,需要用ALTER TABLE 表名称 DROP INDEX 索引名;
#查看索引名 show index from 表名称;
7.5 外部キー制約の要件
-
セカンダリ テーブルに外部キーを作成します。最初にプライマリ テーブルが存在している必要があります。
-
テーブルでは複数の外部キー制約を作成できます
-
通常、スレーブ テーブルの外部キー列はメイン テーブルの主キー列を指している必要があります。
-
スレーブ テーブルの外部キー列の名前とメイン テーブルの参照される列の名前は異なっていてもかまいませんが、データ型は同じである必要があります
7.6 外部キー制約レベル
-
カスケード モード: マスター テーブルのレコードを更新/削除するとき、スレーブ テーブルの一致するレコードを同期的に更新/削除します。
-
Set null メソッド: メインテーブルのレコードを更新/削除するとき、スレーブテーブルの一致するレコードのカラムを null に設定しますが、サブテーブルの外部キーカラムを null にすることはできないことに注意してください。
-
アクションなしモード: 子テーブルに一致するレコードがある場合、親テーブルの対応する候補キーに対する更新/削除操作は許可されません。
-
制限モード: アクションなしと同じで、どちらも外部キー制約をすぐにチェックします。
-
デフォルトの設定方法 (視覚化ツール SQLyog では空白の場合があります): 親テーブルが変更されると、子テーブルは外部キー列をデフォルト値に設定しますが、Innodb はそれを認識できません
レベルが指定されていない場合は、Restrict メソッドと同等です。
7.7 外部キー制約の演習
-- 部门表
create table dept(
id int primary key,
dept_name varchar(50),
dept_location varchar(50)
);
-- 员工表
CREATE TABLE emp(
eid int primary key,
name varchar(50) not null,
sex varchar(10),
dept_id int
);
-- 给员工表表的dept_id添加外键指向部门表的主键
alter table emp add foreign key(dept_id) references dept(id)
第8章 複数のテーブル間の関係
8.1 1対多の関係
8.1.1 概念
1 対多の関係とは、マスター テーブルの 1 行のデータがスレーブ テーブルの複数のデータ行に同時に対応でき、スレーブ テーブルの複数のデータ行が同じ行を指すことを意味します。マスターテーブル内のデータの数。
8.1.2 アプリケーションシナリオ
カテゴリテーブルと製品テーブル、クラステーブルと学生テーブル、ユーザーテーブルと注文テーブルなど。
8.1.2 テーブル作成の原則
片側をメインテーブルとして使用し、マルチ側をスレーブテーブルとして使用し、マスターテーブルの主キーを指す外部キーとしてスレーブテーブルのフィールドを指定します。
8.1.3 Create table ステートメントの練習
-- 创建分类表
CREATE TABLE category(
cid INT PRIMARY KEY AUTO_INCREMENT,
cname VARCHAR(50)
);
-- 创建商品表
CREATE TABLE product(
pid INT PRIMARY KEY AUTO_INCREMENT,
pname VARCHAR(50),
price DOUBLE,
cid INT
)
-- 给商品表添加一个外键
alter table product add foreign key(cid) references category(cid)
8.2 多対多の関係
8.2.1 コンセプト
どちらのテーブルも複数行です。テーブル A のデータ行は、テーブル B の複数行のデータに同時に対応できます。逆に、テーブル B のデータ行は、テーブル A の複数行のデータに対応することもできます。
8.2.2 アプリケーションシナリオ
注文表と商品表、学生表とコース表など。
8.2.3 テーブル作成の原則
2 つのテーブルはマルチパーティであるため、2 つのテーブルに外部キーを作成できないため、新しい中間テーブルを作成する必要があり、中間テーブルに 2 つのフィールドが定義されます。これらの 2 つのフィールドは、ポイントする外部キーとして使用されます。 2 つのテーブルの主キー
8.2.4 Create table ステートメントの練習
-- 创建学生表
CREATE TABLE student(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(50)
);
-- 创建课程表
CREATE TABLE course(
cid INT PRIMARY KEY AUTO_INCREMENT,
cname VARCHAR(20)
);
-- 创建中间表
CREATE TABLE s_c_table(
sno INT,
cno INT
);
-- 给sno字段添加外键指向student表的sid主键
ALTER TABLE s_c_table ADD CONSTRAINT fkey01 FOREIGN KEY(sno) REFERENCES student(sid);
-- 给cno字段添加外键指向course表的cid主键
ALTER TABLE s_c_table ADD CONSTRAINT fkey03 FOREIGN KEY(cno) REFERENCES course(cid);
8.3 1対1の関係(理解)
8.3.1 最初の 1 対 1 の関係
1 対多のリレーションシップについては前に学習しましたが、1 対多のリレーションシップでは、マスター テーブルの 1 行のデータがスレーブ テーブルの複数行のデータに対応するのに対し、スレーブ テーブルのデータ 1 行は対応します。マスター テーブル内の 1 行のデータのみに対応できます。この 1 行のデータと 1 行のデータの対応関係は 1 対 1 の関係とみなすことができます。
3.3.2 2 番目の 1 対 1 の関係
テーブル A のデータ行はテーブル B のデータ行に対応し、その逆も同様で、テーブル B のデータ行はテーブル A のデータ行に対応します。このとき、テーブル A をメインテーブルとテーブル B をスレーブテーブルとして使用するか、B をメインテーブルとして使用します テーブルがメインテーブルとみなされます A テーブルがスレーブテーブルとみなされます
テーブル作成の原理
スレーブテーブルのフィールドを指定して外部キーを作成し、マスターテーブルの主キーを指し、スレーブテーブルの外部キーフィールドに一意性制約を追加します
第 9 章 複数テーブルの関連付けクエリ
マルチテーブル関連付けクエリは、1 つの SQL ステートメントを使用して複数の関連付けられたテーブルのデータをクエリします。
9.1 環境の準備
-- 创建一张分类表(类别id,类别名称.备注:类别id为主键并且自动增长)
CREATE TABLE t_category(
cid INT PRIMARY KEY auto_increment,
cname VARCHAR(40)
);
INSERT INTO t_category values(null,'手机数码');
INSERT INTO t_category values(null,'食物');
INSERT INTO t_category values(null,'鞋靴箱包');
-- 创建一张商品表(商品id,商品名称,商品价格,商品数量,类别.备注:商品id为主键并且自动增长)
CREATE TABLE t_product(
pid INT PRIMARY KEY auto_increment,
pname VARCHAR(40),
price DOUBLE,
num INT,
cno INT
);
insert into t_product values(null,'苹果电脑',18000,10,1);
insert into t_product values(null,'iPhone8s',5500,100,1);
insert into t_product values(null,'iPhone7',5000,100,1);
insert into t_product values(null,'iPhone6s',4500,1000,1);
insert into t_product values(null,'iPhone6',3800,200,1);
insert into t_product values(null,'iPhone5s',2000,10,1);
insert into t_product values(null,'iPhone4s',18000,1,1);
insert into t_product values(null,'方便面',4.5,1000,2);
insert into t_product values(null,'咖啡',10,100,2);
insert into t_product values(null,'矿泉水',2.5,100,2);
insert into t_product values(null,'法拉利',3000000,50,null);
-- 给 商品表添加外键
ALTER TABLE t_product ADD FOREIGN KEY(cno) REFERENCES t_category(cid);
9.2 クロスクエリ【理解】
クロスクエリは実際には、表示のために複数のテーブル内のデータを無条件に接続します。
9.2.1 構文
select a.列,a.列,b.列,b.列 from a,b ;
select a.*,b.* from a,b ;
--或者
select * from a,b;
9.2.2 演習
カテゴリとアイテムの相互参照を使用する
select * from t_category,t_product;
クエリ結果から、クロスクエリが実際には間違ったアプローチであることがわかります。クエリ結果セットには間違ったデータがたくさんあります。クロスクエリ結果セットをデカルト積と呼びます。
9.2.3 デカルト積
セット A={a,b}、セット B={0,1,2} とすると、2 つのセットのデカルト積は {(a,0),(a,1),(a,2),( b,0),(b,1),(b,2)}。複数のコレクションの場合にも拡張できます。
9.3 内部結合クエリ
クロスクエリの結果は私たちが望むものではないため、間違ったレコードや不要なレコードを削除するには、もちろん条件付きフィルターを使用します。通常、クエリ対象の複数のテーブル間に関連付け関係がある場合、**関連付け (主キーと外部キーの関係)** によってデカルト積が削除されます。条件付きフィルタリングによってデカルト積を削除するこの種のクエリは、結合クエリと呼ばれます。結合クエリは内部結合クエリと外部結合クエリに分けられますので、まず内部結合クエリについて学習しましょう。
9.3.1 暗黙的な内部結合クエリ
暗黙的な内部結合クエリに内部結合キーワードがありません
select [字段,字段,字段] from a,b where 连接条件 (b表里面的外键 = a表里面的主键 )
9.3.2 明示的な内部結合クエリ
明示的な内部結合クエリに内部結合キーワードがあります
select [字段,字段,字段] from a [inner] join b on 连接条件 [ where 其它条件]
9.3.3 内部結合クエリの演習
すべてのカテゴリの製品情報をクエリします。このカテゴリに製品がない場合は表示されません。
-- 1 隐式内连接方式
select *from t_category c, t_product p WHERE c.cid = p.cno;
-- 2 显示内连接方式
-- 查询手机数码这个分类下的所有商品的信息以及分类信息
SELECT * FROM t_product tp INNER JOIN t_category tc ON tp.cno = tc.cid WHERE tc.cname = '手机数码';
SELECT * from t_category c INNER JOIN t_product p ON c.cid = p.cno
9.3.4 内部結合クエリの機能
マスターテーブルとスレーブテーブルのデータは、接続条件を満たしていれば問い合わせ可能であり、接続条件を満たしていなければ問い合わせられません。
9.4 外部結合クエリ
内部接続クエリは、接続条件を満たすパブリック部分であることがわかりました。特定のテーブル内のすべてのデータをクエリしたい場合は、外部接続クエリを使用する必要があります。外部接続は、左外部接続と右外部接続に分かれています。外部結合
9.4.1 左外部結合クエリ
9.4.1.1 概念
結合の左側のテーブルをメインテーブルとして使用し、メインテーブルのすべてのデータを表示し、条件に従って右側のテーブルのデータをクエリして接続します。条件が満たされていれば表示されます。そうでない場合は、null として表示されます。これは次のように理解できます:内部接続に基づいて、左側のテーブルのすべてのデータが表示されていることを確認します。
9.4.1.2 構文
select 字段 from a left [outer] join b on 条件
9.4.1.3 演習
すべてのカテゴリの製品情報をクエリします。このカテゴリに製品がない場合でも、このカテゴリの情報を表示する必要があります。
SELECT * FROM t_category c LEFT OUTER JOIN t_product p ON c.cid = p.cno
9.4.2 右外部結合クエリ
9.4.2.1 概念
結合の右側のテーブルをメインテーブルとして使用し、右側のテーブル内のすべてのデータを表示し、条件に従って結合の左側のテーブルのデータをクエリします。条件が満たされる場合、満たされない場合は null が表示されます。これは次のように理解できます:内部接続に基づいて、右側のテーブル内のすべてのデータが表示されていることを確認します。
9.4.2.2 構文
select 字段 from a right [outer] join b on 条件
9.4.2.3 演習
全商品に対応するカテゴリ情報を問い合わせる
SELECT * FROM t_category c RIGHT OUTER JOIN t_product p ON c.cid = p.cno
9.5 ユニオン結合クエリにより完全外部接続クエリを実現
まず第一に、結合クエリは複数テーブル結合クエリの方法ではないことを明確にする必要があります。結合クエリとは、複数のクエリ ステートメントのクエリ結果を 1 つの結果に結合し、重複するデータを削除することです。
完全外部結合クエリとは、左側のテーブルと右側のテーブルのデータをクエリし、接続条件に従って接続することを意味します。
9.5.1 共用体の構文
查询语句1 union 查询语句2 union 查询语句3 ...
9.5.2 演習
# 用左外的A union 右外的B
SELECT * FROM t_category c LEFT OUTER JOIN t_product p ON c.cid = p.cno
union
SELECT * FROM t_category c RIGHT OUTER JOIN t_product p ON c.cid = p.cno
9.6 自己結合クエリ
自己結合クエリは特殊な複数テーブル結合クエリです。これは、関連付けられた 2 つのクエリ テーブルが同じテーブルであり、エイリアスを取得することで 2 つのテーブルに仮想化され、その後 2 つのテーブルの結合クエリを実行するためです。
9.6.1 準備
-- 员工表
CREATE TABLE emp (
id INT PRIMARY KEY, -- 员工id
ename VARCHAR(50), -- 员工姓名
mgr INT , -- 上级领导
joindate DATE, -- 入职日期
salary DECIMAL(7,2) -- 工资
);
-- 添加员工
INSERT INTO emp(id,ename,mgr,joindate,salary) VALUES
(1001,'孙悟空',1004,'2000-12-17','8000.00'),
(1002,'卢俊义',1006,'2001-02-20','16000.00'),
(1003,'林冲',1006,'2001-02-22','12500.00'),
(1004,'唐僧',1009,'2001-04-02','29750.00'),
(1005,'李逵',1006,'2001-09-28','12500.00'),
(1006,'宋江',1009,'2001-05-01','28500.00'),
(1007,'刘备',1009,'2001-09-01','24500.00'),
(1008,'猪八戒',1004,'2007-04-19','30000.00'),
(1009,'罗贯中',NULL,'2001-11-17','50000.00'),
(1010,'吴用',1006,'2001-09-08','15000.00'),
(1011,'沙僧',1004,'2007-05-23','11000.00'),
(1012,'李逵',1006,'2001-12-03','9500.00'),
(1013,'小白龙',1004,'2001-12-03','30000.00'),
(1014,'关羽',1007,'2002-01-23','13000.00');
#查询孙悟空的上级
SELECT employee.*,manager.ename mgrname FROM emp employee,emp manager where employee.mgr=manager.id AND employee.ename='孙悟空'
9.6.2 自己結合クエリの演習
従業員の番号、名前、給与とそのリーダーの番号、名前、給与を照会します。
#这些数据全部在员工表中
#把t_employee表,即当做员工表,又当做领导表
#领导表是虚拟的概念,我们可以通过取别名的方式虚拟
SELECT employee.id "员工的编号",emp.ename "员工的姓名" ,emp.salary "员工的薪资",
manager.id "领导的编号" ,manager.ename "领导的姓名",manager.salary "领导的薪资"
FROM emp employee INNER JOIN emp manager
#emp employee:employee.,表示的是员工表的
#emp manager:如果用manager.,表示的是领导表的
ON employee.mgr = manager.id # 员工的mgr指向上级的id
#表的别名不要加"",给列取别名,可以用"",列的别名不使用""也可以,但是要避免包含空格等特殊符号。
第 10 章 サブクエリ
クエリ ステートメントが別のクエリ ステートメントにネストされている場合、このクエリ ステートメントはサブクエリと呼ばれ、位置の違いに応じて where 型、from 型、exists 型に分割されます。注: サブクエリがどこにあっても、サブクエリは () で囲む必要があります。
10.1 where型
① サブクエリが単一値の結果 (単一行、単一列) の場合、それを使用できます (=、> およびその他の比較演算子)。
# 查询价格最高的商品信息
select * from t_product where price = (select max(price) from t_product)
②サブクエリは多値の結果なので、([not] in (サブクエリ結果)、または >all (サブクエリ結果)、または >=all (サブクエリ結果)、< を使用できます。 all (サブクエリ結果)、<=all(サブクエリ結果)、または >any(サブクエリ結果)、または >=any(サブクエリ結果)、<any(サブクエリ結果)、<=any(サブクエリ結果))
# 查询价格最高的商品信息
SELECT * FROM t_product WHERE price >=ALL(SELECT price FROM t_product)
select * from t_product order by price desc limit 0,1
10.2 タイプから
サブクエリの結果は、テーブルと同様に、複数の行と複数の列の結果です。
サブクエリには別名、つまり一時テーブルの名前を付ける必要があります。テーブルの別名に「」やスペースを追加しないでください。
-- 思路一: 使用连接查询
-- 使用外连接,查询出分类表的所有数据
SELECT tc.cname,COUNT(tp.pid) FROM t_category tc LEFT JOIN t_product tp ON tp.cno = tc.cid GROUP BY tc.cname
-- 思路二: 使用子查询
-- 第一步:对t_product根据cno进行分组查询,统计每个分类的商品数量
SELECT cno,COUNT(pid) FROM t_product GROUP BY cno
-- 第二步: 用t_category表去连接第一步查询出来的结果,进行连接查询,此时要求查询出所有的分类
SELECT tc.cname,IFNULL(tn.total,0) '总数量' FROM t_category tc LEFT JOIN (SELECT cno,COUNT(pid) total FROM t_product GROUP BY cno) tn ON tn.cno=tc.cid
10.3 存在型
# 查询那些有商品的分类
SELECT cid,cname FROM t_category tc WHERE EXISTS (SELECT * FROM t_product tp WHERE tp.cno = tc.cid);