MySQL中定义fk语句_MySQL基础篇/第3篇:MySQL基本操作语句.md · qwqoo/MySQL-Review - Gitee.com...
### 第3篇:MySQL基本操作语句
- MySQL基础操作
#### 排序检索数据
- 之前的数据没有进行排序,其是按照默认在数据表中的数据返回的
- SELECT语句的ORDER BY 子句进行排序
```mysql
# 没有特定的顺序查询 (虽然结果看起来是有序的,是因为数据表中就是这个顺序)
SELECT username FROM test;
```

- **子句:** SQL语句由子句构成,有些子句是必须的,有些则是可选的。一个子句通常由一个关键字和所提供的数据组成。子句的例子有SELECT语句的FROM子句。
- 如果要明确排序检索出来的数据,则使用 ORDER BY 子句
- 例子如下
```mysql
# 默认是升序的 省略了 asc 下面的等价
SELECT username FROM test ORDER BY username;
SELECT username FROM test ORDER BY username asc;
# 后面加上 desc 则是降序
SELECT username FROM test ORDER BY username desc;
```


- 也可以按照多个列进行排序
```mysql
# 先按照 username 降序,如果username一样,再按照id升序
SELECT id,username,password FROM test ORDER BY username desc,id asc;
# 先按照 username 升序,如果username一样,再按照id降序
SELECT id,username,password FROM test ORDER BY username asc,id asc;
# 在多个列上降序排序 如果想在多个列上进行降序排序,必须对每个列指定DESC关键字。
```

- ORDER BY 和 LIMIT 的组合
```mysql
# 先按照 username 升序,如果username一样,再按照id降序,只取出一条结果
SELECT id,username,password FROM test ORDER BY username asc,id asc LIMIT 1;
```

#### 过滤数据
- 使用SELECT的WHERE子句搜索指定的搜索条件
```mysql
# 查询名字为 hello 的人
SELECT id,username,password FROM test WHERE username = 'hello';
```

- 数据的过滤也可以在应用中,如Java项目中,先拿到数据,然后在Java内存中进行数据的过滤。
- WHERE 子句的位置,在同时使用ORDER BY 和 WHERE子句的时候,应该让ORDER BY 在WHERE之后,否则会报错
```mysql
# 正确写法
SELECT id,username,password FROM test WHERE username = 'hello' ORDER by username asc;
# 错误写法
SELECT id,username,password FROM test ORDER by username asc WHERE username = 'hello';
```

- WHERE 子句的操作符
| 操作符 | 说明 |
| --------------- | ------------------ |
| = | 等于 |
| <> | 不等于 |
| ! | 不等于 |
| < | 小于 |
| <= | 小于等于 |
| > | 大于 |
| >= | 大于等于 |
| BETWEEN xxx AND | 在指定的两个值之间 |
- 测试SQL
```mysql
SELECT id,username,password FROM test WHERE id >= 2;
SELECT id,username,password FROM test WHERE id >= 2 AND id <=5;
SELECT id,username,password FROM test WHERE id BETWEEN 2 AND 5;
```

- 空值检查
```mysql
SELECT username,password FROM test WHERE username IS NOT NULL;
```

#### 数据过滤
- WHERE 子句和NOT、IN、AND 的操作
- WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件
```mysql
# AND操作符
SELECT id,username,password FROM test WHERE id >= 2 AND id <=5;
# OR 操作符
SELECT id,username,password FROM test WHERE id = 2 OR id =5;
```

- 组合AND和OR会带来一个问题。其会有一个计算的优先级,也就是说 AND优先于OR先执行
```mysql
# 从下面的查询结果来看,需要查询的数据 id > 1,但是等于 id=1 的结果也被查询出来,原因就是AND会优先于OR执行
SELECT id,username,password FROM test WHERE username = 'hello' OR username = 'hello1' AND id > 1;
# 合理的操作
SELECT id,username,password FROM test WHERE (username = 'hello' OR username = 'hello1' )AND id > 1;
```


- IN 操作符的使用
```mysql
SELECT id,username FROM test WHERE id IN (1,2,3);
SELECT id,username FROM test WHERE id NOT IN (1,2,3);
SELECT id,username FROM test WHERE id NOT IN (1,2,3) ORDER BY username;
SELECT id,username FROM test WHERE id NOT IN (1,2,3) ORDER BY username desc;
```


#### 使用通配符进行过滤
- LIKE 通配符 LIKE 是一个关键字
- **通配符(wildcard)** 用来匹配值的一部分的特殊字符。
- **搜索模式(search pattern)** 由字面值、通配符或者两者组合构成的搜索条件
- % 通配符,表示任意字符出现的任意次数
```mysql
SELECT id,username,password FROM test WHERE username LIKE 'he%';
SELECT id,username,password FROM test WHERE username LIKE '%o';
# 搜索内容不区分大小写,但是可以进行配置,是否区分大小写,这里涉及到数据库的排序方式
SELECT id,username,password FROM test WHERE username LIKE 'He%';
# 其他操作 搜索 %e% 表示匹配任何包含e的文本的值,无论前面后面是什么
SELECT id,username,password FROM test WHERE username LIKE '%e%';
# 找出h开头,1结尾的内容
SELECT id,username,password FROM test WHERE username LIKE 'h%1';
```


- 下划线通配符 _ 其只能匹配一个字符
```mysql
SELECT id,username,password FROM test WHERE username LIKE '_ello';
```

- **建议:**
- 不要过度使用通配符
- 把搜索模式放在开头,也就是把 % 或者 _ 放在搜索条件开头,是最慢的,因为其不会走索引(之后会说)
- 需要注意通配符的位置,不要放错了
#### 用正则表达式进行搜索
- 正则表达式是用来匹配文本的特殊的串(字符集合)
```mysql
# 查询姓名包含 ello 的所有的行
SELECT id,username,password FROM test WHERE username REGEXP 'ello';
# 简单的正则表达式
SELECT id,username,password FROM test WHERE username REGEXP '.llo';
# 正则表达式的性能不稳定,有时候可能会更差,本人不推荐使用
# 正则表达式匹配不区分大小写,如果想区分大小写,可以这样写
SELECT id,username,password FROM test WHERE username REGEXP BINARY '.llo';
```



- 使用正则表达式进行OR匹配
```mysql
# 匹配 lo 或者 e
SELECT id,username,password FROM test WHERE username REGEXP BINARY 'lo|e';
```

- 匹配几个字符之一
```mysql
SELECT id,username,password FROM test WHERE username REGEXP '[llo] 1';
SELECT id,username,password FROM test WHERE username REGEXP '[llo]1';
# 上面的正则表达式等价于
# [llo] 1 => l 1、l 1、o 1
# [llo]1 => l1、l1、o1
# [] 是一种特殊形式的 OR
```

- 匹配范围
```mysql
SELECT id,username,password FROM test WHERE username REGEXP '[a-z]1';
SELECT id,username,password FROM test WHERE username REGEXP '[A-Z]1';
SELECT id,username,password FROM test WHERE username REGEXP BINARY '[A-Z]1';
```

- 匹配特殊字符,如果想匹配 .、[]、|和-等特市字符,怎么搜索?
```mysql
# 这个是通配符,不是我们想要的,所以需要转义
SELECT id,username,password FROM test WHERE username REGEXP '.';
# 在需要转义之前加上 \\
SELECT id,username,password FROM test WHERE username REGEXP '\\.';
```

| 类 | 说明 |
| ---------- | ------------------------------------------------- |
| [:alnum:] | 任意字母和数字(同[a-zA-Z0-9]) |
| [:alpha:] | 任意字符(同[a-zA-Z]) |
| [:blank:] | 空格和制表(同[\\t]) |
| [:cntrl:] | ASCII控制字符(ASCII 0到31和127) |
| [:digit:] | 任意数字(同[0-9]) |
| [:graph:] | 与[:print:]相同,但不包括空格 |
| [:lower:] | 任意小写字母(同[a-z]) |
| [:print:] | 任意可打印字符 |
| [:punct:] | 既不在[:alnum:]又不在[:cntrl:]中的任意字符 |
| [:space:] | 包括空格在内的任意空白字符(同[\\f\\n\\r\\t\\v]) |
| [:upper:] | 任意大写字母(同[A-Z]) |
| [:xdigit:] | 任意十六进制数字(同[a-fA-F0-9]) |
| 元字符 | 说明 |
| ------ | ---------------------------- |
| * | 0个或多个匹配 |
| + | 1个或多个匹配(等于{1,}) |
| ? | 0个或1个匹配(等于{0,1}) |
| {n} | 指定数目的匹配 |
| {n,} | 不少于指定数目的匹配 |
| {n,m} | 匹配数目的范围(m不超过255) |
- 例子
```mysql
SELECT id,username,password FROM test WHERE username REGEXP '\\([0-9] hello?\\)';
# 正则表达式\\([0-9] hello?\\)需要解说一下。\\(匹配),[0-9]匹配任意数字,hello?匹配hello和hello(s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出现),\\)匹配) 没有?,匹配hello和hellos会非常困难
```
- 例子
```mysql
# 匹配连载一起的4个数字
SELECT id,username,password FROM test WHERE username REGEXP '[:digit:]{4}';
```
| 元字符 | 说明 |
| ------- | ---------- |
| ^ | 文本的开始 |
| $ | 文本的结尾 |
| [[:<:>
| [[:>:]] | 词的结尾 |
- 如果你想找出以一个数(包括以小数点开始的数)开始的所有产品,怎么办?简单搜索[0-9\\.](或[[:digit:]\\.])不行,因为它将在文本内任意位置查找匹配。解决办法是使用^定位符
```mysql
SELECT id,username,password FROM test WHERE username REGEXP '^[0-9\\.]';
# ^匹配串的开始。因此,^[0-9\\.]只在.或任意数字为串中第一个字符时才匹配它们
# ^的双重用途 ^有两种用法。在集合中(用[和]定义),用它来否定该集合,否则,用来指串的开始处。
```
#### 创建计算字段
- 存储在表中的数据都不是应用程序所需要的。我们需要直接从数据库中检索出转换、计算或格式化过的数据;而不是检索出数据,然后再在客户机应用程序或报告程序中重新格式化。这就是计算字段的作用。
- **字段(field)** 基本上与列(column)的意思相同,经常互换使用,不过数据库列一般称为列,而术语字段通常用在计算字段的连接上。
- 性能问题:可在SQL语句内完成的许多转换和格式化工作都可以直接在客户机应用程序内完成。但一般来说,在数据库服务器上完成这些操作比在客户机中完成要快得多,因为DBMS是设计来快速有效地完成这种处理的。
- 拼接字段(concatenate):将值联结在一起构成单个值。使用MySQL内置函数 Concat() 拼接两个列。
```mysql
SELECT Concat(id,'(',username,')') FROM test;
```

- 去除空格的函数 RTrim() 去除右侧的空格,LTrim() 去除左边的空格,Trim() 去除空格
``` mysql
SELECT Concat(RTrim(username)) FROM test;
```

- 使用别名 as 或者省略
```mysql
SELECT Concat(RTrim(username)) as name FROM test;
# as 可以省略,但是必须加上空格
SELECT Concat(RTrim(username)) name FROM test;
```

- 执行算术计算 如 + 、- 、* 、/ MySQL 都是支持的
```mysql
# 注意,下面的计算结果毫无意义,只是为了演示语法,一般的,id不参与计算
SELECT id*10 10TimesId FROM test where id = 1;
```

#### 使用数据处理函数
- MySQL支持函数,SQL利用函数来处理数据
- SQL包括的函数
- 用于处理文本(删除、拼接、去除空格、转换值为大写或者小写)
- 用于在数值上进行算术操作
- 用于处理日期和时间值并且从这些值中提取特定成分的日期和时间函数
- 返回DBMS正使用的特殊信息的系统函数
- 文本处理函数
```mysql
SELECT username,Upper(username) FROM test;
```

| 函数 | 说明 |
| ----------- | ----------------- |
| Left() | 返回串左边的字符 |
| Length() | 返回串的长度 |
| Locate() | 找出串的一个子串 |
| Lower() | 将串转换为小写 |
| LTrim() | 去掉串左边的空格 |
| Right() | 返回串右边的字符 |
| RTrim() | 去掉串右边的空格 |
| Soundex() | 返回串的SOUNDEX值 |
| SubString() | 返回子串的字符 |
| Upper() | Upper() |
- 注意:SOUNDEX是一个将任何文本串转换为描述其语音表示的字母数字模式的算法。SOUNDEX考虑了类似的发音字符和音节,使得能对串进行发音比较而不是字母比较。虽然SOUNDEX不是SQL概念。
- 日期和时间处理函数
| 函数 | 说明 |
| ------------- | ------------------------------ |
| AddDate() | 增加一个日期(天,周等) |
| AddTime() | 增加一个时间(时,分等) |
| CurDate() | 返回当前日期 |
| CurTime() | 返回当前时间 |
| Date() | 返回日期时间的日期部分 |
| DateDiff() | 计算两个日期之差 |
| Date_Add() | 高度灵活的日期运算函数 |
| Date_Format() | 返回一个格式化的日期或者字符串 |
| Day() | 返回一个日期的天数部分 |
| DayOfWeek() | 对于一个日期,返回对应的星期几 |
| Hour() | 返回一个时间的小时部分 |
| Minute() | 返回一个时间的分钟部分 |
| Month() | 返回一个日期的月份部分 |
| Now() | 返回当前日期和时间 |
| Second() | 返回一个时间的秒部分 |
| Time() | 返回一个日期时间的时间部分 |
| Year() | 返回一个日期的年份部分 |
- 案例
```mysql
SELECT id,username FROM test WHERE create_time = '2020-12-19 08:52:48';
```

- 使用部分日期进行比较得出结果
```mysql
SELECT id,username FROM test WHERE Date(create_time) = '2020-12-19';
```

- 如果想检索某年某月的数据
```mysql
# 第一种方法
SELECT id,username FROM test WHERE Date(create_time) BETWEEN '2020-12-01' AND '2020-12-31';
# 第二种方法
SELECT id,username FROM test WHERE Year(create_time) = 2020 AND Month(create_time) = 12;
```

- 数值处理函数
| 函数 | 说明 |
| ------ | ------------------ |
| Abs() | 返回一个数的绝对值 |
| Cos() | 返回一个角度的余弦 |
| Exp() | 返回一个数的指数值 |
| Mod() | 返回除操作的余数 |
| Pi() | 返回圆周率 |
| Rand() | 返回一个随机数 |
| Sin() | 返回一个角度的正弦 |
| Sqrt() | 返回一个数的平方根 |
| Tan() | 返回一个角度的正切 |
#### 聚集函数
- 聚集函数(aggregate function) 运行在行组上,计算和返回单个值的函数
| 函数 | 说明 |
| ------- | ---------------- |
| AVG() | 返回某列的平均值 |
| COUNT() | 返回某列的行数 |
| MAX() | 返回某列的最大值 |
| MIN() | 返回某列的最小值 |
| SUM() | 返回某列的和 |
- 注意点:AVG() 会忽略空值的行。COUNT(\*) 和 COUNT(某列)的区别 COUNT(\*)对表中行的数目计数,无论表列中包含的是不是空值。COUNT(某列)对列中具有值得行进行计数,忽略NULL值。MAX(某列) 忽略列值为NULL的行
- 以上的聚集函数都可以这样使用
- 对所有的行执行计算,指定ALL参数或者不给参数(因为ALL是默认行为)
- 只包含不同的值,使用 DISTINCT 参数
```mysql
# 只是以此为例
SELECT id,AVG(DISTINCT id) FROM test;
```
#### 分组数据
- 数据分组:关键语句 GROUP BY
```mysql
SELECT COUNT(username),username FROM test GROUP BY username;
```

- 规定
- GROUP BY 子句可以包含任意数目的列。这使得能对分组进行嵌套,为数据分组提供更细致的控制。
- 如果在GROUP BY 子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组的时候,指定的所有的列都是一起计算的(所以不能从个别的列取回数据)
- GROUP BY 子句中列出的每个列都必须是检索列或者是有效的表达式(但是不能是聚集函数),如果SELECT 中使用表达式,则必须在GROUP BY 子句中指定相同的表达式,不能使用别名。
- 除了聚集计算语句外,SELECT 语句中的每个列都必须在GROUP BY 子句中给出。
- 如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为1组。
- GROUP BY 子句必须出现在WHERE子句之后,ORDER BY 子句之前
- 使用ROLLUP 使用WITH ROLLUP关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值
```mysql
SELECT COUNT(username),username FROM test GROUP BY username WITH ROLLUP;
```

- **过滤分组:** 规定包含哪些分组,不包含哪些分组,例如:得到至少有2个订单的所有的顾客
- WHERE子句的作用,过滤的是行而不是分组,WHERE 没有分组的概念
- HAVING 子句,HAVING子句非常类似于WHERE。事实上,目前学过的所有类型的WHERE子句都可以使用HAVING来替代,唯一的差别是WHERE过滤行,HAVING过滤分组。HAVING支持所有的的WHERE操作符。
```mysql
SELECT COUNT(username),username FROM test GROUP BY username WITH ROLLUP HAVING COUNT(username) >=2 ;
```

- HAVING和WHERE的差别 这里有另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。这是一个重要的区别,WHERE排除的行不包括在分组中。这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组。
```mysql
SELECT COUNT(username),username FROM test WHERE id >2 GROUP BY username WITH ROLLUP HAVING COUNT(username) >=2 ;
```

- 分组和排序
| ORDER BY | GROUP BY |
| -------------------------------------------- | -------------------------------------------------------- |
| 排序产生的输出 | 分组行。但输出可能不是分组的顺序 |
| 任意列都可以使用(甚至非选择的列也可以使用) | 只可能使用选择列或表达式列,而且必须使用每个选择列表达式 |
| 不一定需要 | 如果与聚集函数一起使用列(或表达式),则必须使用 |
- **SELECT 子句顺序**
| 子句 | 说明 | 是否必须使用 |
| -------- | -------------------- | ------------------------ |
| SELECT | 要返回的列或者表达式 | 是 |
| FROM | 从中检索数据的表 | 仅在从表选择数据时使用 |
| WHERE | 行级过滤 | 否 |
| GROUP BY | 分组说明 | 仅在按组计算聚集时候使用 |
| HAVING | 组级过滤 | 否 |
| ORDER BY | 输出排序顺序 | 否 |
| LIMIT | 要检索的行数 | 否 |
#### 使用子查询
- 查询(query)任何SQL语句都是查询。但此术语一般指SELECT语句。
- **创建数据表和数据(在文末 案例SQL数据)**
- 订单存储在两个表中。对于包含订单号、客户ID、订单日期的每个订单,orders表存储一行。各订单的物品存储在相关的orderitems表中。orders表不存储客户信息。它只存储客户的ID。实际的客户信息存储在customers表中。
- 现在,假如需要列出订购物品TNT2的所有客户,应该怎样检索?下面列出具体的步骤。
- 检索包含物品 TNT2 的所有订单的编号
- 检索具有前一步骤列出的订单编号的所有的客户的ID
- 检索上一步骤返回的所有客户ID的客户信息
- 上述的每个步骤都可以单独使用一个查询来执行,可以把一条SELECT语句返回结果用于另一条SELECT的WHERE语句
- 也可以使用子查询语句把3个查询组合成一条语句
```mysql
# 第一个查询
SELECT order_num FROM orderitems WHERE prod_id = 'TNT2';
# 第二个查询
SELECT cust_id FROM orders WHERE order_num IN (20005,20007);
# 合并之后
SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = 'TNT2');
```

- 在SELECT语句中,子查询总是从内向外处理。在处理上面的SELECT语句时,MySQL实际上执行了两个操作。
- 首先,它执行下面的查询:`SELECT order_num FROM orderitems WHERE prod_id = 'TNT2'` 此查询返回两个订单号:20005和20007。
- 然后,这两个值以IN操作符要求的逗号分隔的格式传递给外部查询的WHERE子句。外部查询变成:`SELECT cust_id FROM orders WHERE order_num IN (20005,20007);`
- 现在得到了订购物品TNT2的所有客户的ID。下一步是检索这些客户ID的客户信息。检索两列的SQL语句为:
```mysql
SELECT cust_name,cust_contact FROM customers WHERE cust_id IN (10001,10004);
```

- 合并SQL语句进行查询
```mysql
SELECT cust_name,cust_contact FROM customers WHERE cust_id IN (SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = 'TNT2'));
```

- 为了执行上述SELECT语句,MySQL实际上必须执行3条SELECT语句。最里边的子查询返回订单号列表,此列表用于其外面的子查询的WHERE子句。外面的子查询返回客户ID列表,此客户ID列表用于最外层查询的WHERE子句。最外层查询确实返回所需的数据。\
- **作为计算字段使用子查询**
- 假如需要显示customers表中每个客户的订单总数。订单与相应的客户ID存储在orders表中。
- 为了执行这个操作,遵循下面的步骤
- 从customers 表中检索客户列表
- 对于检索处的每个客户,统计其在orders表中的订单数目
```mysql
# 对客户10001的订单进行计数
SELECT COUNT(*) AS orders FROM orders WHERE cust_id = 10001;
# 对每个客户执行COUNT(*)计算,应该将COUNT(*)作为一个子查询
SELECT cust_name,cust_state,(SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name;
```

- 相关子查询(correlated subquery)涉及外部查询的子查询。这种类型的子查询称为相关子查询。任何时候只要列名可能有多义性,就必须使用这种语法(表名和列名由一个句点分隔)。这是为了确定某个数据确实是来自某张表,避免了笛卡尔积。
#### 案例SQL数据
```mysql
########################################
# MySQL Crash Course
# http://www.forta.com/books/0672327120/
# Example table creation scripts
########################################
########################
# Create customers table
########################
CREATE TABLE customers
(
cust_id int NOT NULL AUTO_INCREMENT,
cust_name char(50) NOT NULL ,
cust_address char(50) NULL ,
cust_city char(50) NULL ,
cust_state char(5) NULL ,
cust_zip char(10) NULL ,
cust_country char(50) NULL ,
cust_contact char(50) NULL ,
cust_email char(255) NULL ,
PRIMARY KEY (cust_id)
) ENGINE=InnoDB;
#########################
# Create orderitems table
#########################
CREATE TABLE orderitems
(
order_num int NOT NULL ,
order_item int NOT NULL ,
prod_id char(10) NOT NULL ,
quantity int NOT NULL ,
item_price decimal(8,2) NOT NULL ,
PRIMARY KEY (order_num, order_item)
) ENGINE=InnoDB;
#####################
# Create orders table
#####################
CREATE TABLE orders
(
order_num int NOT NULL AUTO_INCREMENT,
order_date datetime NOT NULL ,
cust_id int NOT NULL ,
PRIMARY KEY (order_num)
) ENGINE=InnoDB;
#######################
# Create products table
#######################
CREATE TABLE products
(
prod_id char(10) NOT NULL,
vend_id int NOT NULL ,
prod_name char(255) NOT NULL ,
prod_price decimal(8,2) NOT NULL ,
prod_desc text NULL ,
PRIMARY KEY(prod_id)
) ENGINE=InnoDB;
######################
# Create vendors table
######################
CREATE TABLE vendors
(
vend_id int NOT NULL AUTO_INCREMENT,
vend_name char(50) NOT NULL ,
vend_address char(50) NULL ,
vend_city char(50) NULL ,
vend_state char(5) NULL ,
vend_zip char(10) NULL ,
vend_country char(50) NULL ,
PRIMARY KEY (vend_id)
) ENGINE=InnoDB;
###########################
# Create productnotes table
###########################
CREATE TABLE productnotes
(
note_id int NOT NULL AUTO_INCREMENT,
prod_id char(10) NOT NULL,
note_date datetime NOT NULL,
note_text text NULL ,
PRIMARY KEY(note_id),
FULLTEXT(note_text)
) ENGINE=MyISAM;
#####################
# Define foreign keys
#####################
ALTER TABLE orderitems ADD CONSTRAINT fk_orderitems_orders FOREIGN KEY (order_num) REFERENCES orders (order_num);
ALTER TABLE orderitems ADD CONSTRAINT fk_orderitems_products FOREIGN KEY (prod_id) REFERENCES products (prod_id);
ALTER TABLE orders ADD CONSTRAINT fk_orders_customers FOREIGN KEY (cust_id) REFERENCES customers (cust_id);
ALTER TABLE products ADD CONSTRAINT fk_products_vendors FOREIGN KEY (vend_id) REFERENCES vendors (vend_id);
```
```mysql
########################################
# MySQL Crash Course
# http://www.forta.com/books/0672327120/
# Example table population scripts
########################################
##########################
# Populate customers table
##########################
INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(10001, 'Coyote Inc.', '200 Maple Lane', 'Detroit', 'MI', '44444', 'USA', 'Y Lee', 'ylee@coyote.com');
INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES(10002, 'Mouse House', '333 Fromage Lane', 'Columbus', 'OH', '43333', 'USA', 'Jerry Mouse');
INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(10003, 'Wascals', '1 Sunny Place', 'Muncie', 'IN', '42222', 'USA', 'Jim Jones', 'rabbit@wascally.com');
INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(10004, 'Yosemite Place', '829 Riverside Drive', 'Phoenix', 'AZ', '88888', 'USA', 'Y Sam', 'sam@yosemite.com');
INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES(10005, 'E Fudd', '4545 53rd Street', 'Chicago', 'IL', '54545', 'USA', 'E Fudd');
########################
# Populate vendors table
########################
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1001,'Anvils R Us','123 Main Street','Southfield','MI','48075', 'USA');
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1002,'LT Supplies','500 Park Street','Anytown','OH','44333', 'USA');
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1003,'ACME','555 High Street','Los Angeles','CA','90046', 'USA');
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1004,'Furball Inc.','1000 5th Avenue','New York','NY','11111', 'USA');
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1005,'Jet Set','42 Galaxy Road','London', NULL,'N16 6PS', 'England');
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1006,'Jouets Et Ours','1 Rue Amusement','Paris', NULL,'45678', 'France');
#########################
# Populate products table
#########################
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('ANV01', 1001, '.5 ton anvil', 5.99, '.5 ton anvil, black, complete with handy hook');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('ANV02', 1001, '1 ton anvil', 9.99, '1 ton anvil, black, complete with handy hook and carrying case');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('ANV03', 1001, '2 ton anvil', 14.99, '2 ton anvil, black, complete with handy hook and carrying case');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('OL1', 1002, 'Oil can', 8.99, 'Oil can, red');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('FU1', 1002, 'Fuses', 3.42, '1 dozen, extra long');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('SLING', 1003, 'Sling', 4.49, 'Sling, one size fits all');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('TNT1', 1003, 'TNT (1 stick)', 2.50, 'TNT, red, single stick');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('TNT2', 1003, 'TNT (5 sticks)', 10, 'TNT, red, pack of 10 sticks');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('FB', 1003, 'Bird seed', 10, 'Large bag (suitable for road runners)');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('FC', 1003, 'Carrots', 2.50, 'Carrots (rabbit hunting season only)');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('SAFE', 1003, 'Safe', 50, 'Safe with combination lock');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('DTNTR', 1003, 'Detonator', 13, 'Detonator (plunger powered), fuses not included');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('JP1000', 1005, 'JetPack 1000', 35, 'JetPack 1000, intended for single use');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('JP2000', 1005, 'JetPack 2000', 55, 'JetPack 2000, multi-use');
#######################
# Populate orders table
#######################
INSERT INTO orders(order_num, order_date, cust_id)
VALUES(20005, '2005-09-01', 10001);
INSERT INTO orders(order_num, order_date, cust_id)
VALUES(20006, '2005-09-12', 10003);
INSERT INTO orders(order_num, order_date, cust_id)
VALUES(20007, '2005-09-30', 10004);
INSERT INTO orders(order_num, order_date, cust_id)
VALUES(20008, '2005-10-03', 10005);
INSERT INTO orders(order_num, order_date, cust_id)
VALUES(20009, '2005-10-08', 10001);
###########################
# Populate orderitems table
###########################
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 1, 'ANV01', 10, 5.99);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 2, 'ANV02', 3, 9.99);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 3, 'TNT2', 5, 10);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 4, 'FB', 1, 10);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20006, 1, 'JP2000', 1, 55);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 1, 'TNT2', 100, 10);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 1, 'FC', 50, 2.50);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 1, 'FB', 1, 10);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 2, 'OL1', 1, 8.99);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 3, 'SLING', 1, 4.49);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 4, 'ANV03', 1, 14.99);
#############################
# Populate productnotes table
#############################
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(101, 'TNT2', '2005-08-17',
'Customer complaint:
Sticks not individually wrapped, too easy to mistakenly detonate all at once.
Recommend individual wrapping.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(102, 'OL1', '2005-08-18',
'Can shipped full, refills not available.
Need to order new can if refill needed.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(103, 'SAFE', '2005-08-18',
'Safe is combination locked, combination not provided with safe.
This is rarely a problem as safes are typically blown up or dropped by customers.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(104, 'FC', '2005-08-19',
'Quantity varies, sold by the sack load.
All guaranteed to be bright and orange, and suitable for use as rabbit bait.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(105, 'TNT2', '2005-08-20',
'Included fuses are short and have been known to detonate too quickly for some customers.
Longer fuses are available (item FU1) and should be recommended.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(106, 'TNT2', '2005-08-22',
'Matches not included, recommend purchase of matches or detonator (item DTNTR).'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(107, 'SAFE', '2005-08-23',
'Please note that no returns will be accepted if safe opened using explosives.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(108, 'ANV01', '2005-08-25',
'Multiple customer returns, anvils failing to drop fast enough or falling backwards on purchaser. Recommend that customer considers using heavier anvils.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(109, 'ANV03', '2005-09-01',
'Item is extremely heavy. Designed for dropping, not recommended for use with slings, ropes, pulleys, or tightropes.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(110, 'FC', '2005-09-01',
'Customer complaint: rabbit has been able to detect trap, food apparently less effective now.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(111, 'SLING', '2005-09-02',
'Shipped unassembled, requires common tools (including oversized hammer).'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(112, 'SAFE', '2005-09-02',
'Customer complaint:
Circular hole in safe floor can apparently be easily cut with handsaw.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(113, 'ANV01', '2005-09-05',
'Customer complaint:
Not heavy enough to generate flying stars around head of victim. If being purchased for dropping, recommend ANV02 or ANV03 instead.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(114, 'SAFE', '2005-09-07',
'Call from individual trapped in safe plummeting to the ground, suggests an escape hatch be added.
Comment forwarded to vendor.'
);
```
#### 参考
- 《MySQL必知必会》
一键复制
编辑
Web IDE
原始数据
按行查看
历史
相关文章:

如何高效推进ML模型开发和部署?Uber机器学习平台Michelangelo实践
作者 | Jeremy Hermann & Mike Del Balso 译者 | 王天宇 整理 | Jane 出品 | AI科技大本营 【导读】2017年9月,Uber 在技术社区发表了一篇文章向大家介绍了 Uber 的机器学习平台 —— Michelangelo。随着平台的日渐成熟,Uber 的业务数量与能力也随…

Api 函数: GetCursorPos 与转换
//获取鼠标在窗体中的当前位置 procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); varstr: string; beginstr : Format(%d,%d,[X,Y]);ShowMessage(str); end;//用 GetCursorPos 获取的是鼠标相对与屏幕的位置 varps:…

向下滚动页面导航悬浮
为什么80%的码农都做不了架构师?>>> 做两个导航,第二个隐藏 下拉到一定位置,显示第二个,position:fixed $(function(){$(window).scroll(function () {var top $(document).scrollTop();var m$(".nav")…

胜过iPhone XS?Google Pixel的“夜视功能”是怎样炼成的
作者 | Marc Levoy、Yael Pritch译者 | 刘旭坤整理 | Jane出品 | AI科技大本营【导读】随着智能手机的不断发展成熟,为了寻找差异化的厂商不断增加摄像头的数量。然而,摄像头的数量越多,就代表拍照的质量越好吗?Google Pixel 手机…

npm导入bootstrap_vue cli3.0如何通过npm引入jquery和bootstrap?
不建议通过npm的方式引入这两个东西,因为这两个东西本身就是打包好的,通过npm的方式过去,还得在webpack中排除掉,迂回。要用就直接在html中通过script和link标签引入。jQuery是时代的产物,如果要用到vue,那…

ABAP 一个隐藏 selection-screen block的实例
以下是一个演示如何通过 selection-screen 中的pushbutton来动态改变屏幕上的字段的显示状态的(即显示或者隐藏)。注意:显示 通过本示例可知selection-screen 中的 field 的显示状态都是 的,在程序中修改其属性 active 的值为 0 时…

python计算文件中字母出现次数_python – 计算文本文件中字母的频率
使用collections.Counter():from collections import Counterwith open(file) as f:c Counter()for x in f:c Counter(x.strip())正如mgilson指出的那样,如果文件不是那么大,你可以简单地做:c Counter(f.read().strip())例:>>> c…

公开课报名 | 详解CNN-pFSMN模型以及在语音识别中的应用
近年来,在深度学习技术的帮助下,语音识别取得了极大的进展,从实验室开始走向市场,走向实用化。基于语音识别技术的输入法、搜索和翻译等人机交互场景都有了广泛的应用。Librispeech是当前衡量语音识别技术的最权威主流的开源数据集…

Ruby开发环境配置
一、 RoR IDE http://deadlock.netbeans.org/hudson/job/ruby/ 你可以从这个地方下载Ruby IDE专用版本的netbeans,只有30MB大小,速度比RadRails还快!netbeans的RoR支持很强大,但也要注意两点: 1) 一定要用JDK6.0&am…

net localgroup 命令详解
http://www.jb51.net/article/24733.htm windows 核心安装中,关闭防火墙的命令 netsh advfirewall set allprofiles state off Hyper-v使用远程管理工具的相关设置: http://technet.microsoft.com/zh-cn/library/cc794756(vws.10).aspx 在SCVMM中添加Hyp…

ii 第七单元 访问网络共享文件系统
挂载网络文件系统 网络文件系统是由网络附加存储服务器通过网络向多个主机提供的一种文件系统 , 而不是由块设备 ( 例如硬盘驱动器 ) 提供的。客户端通过特殊的文件系统协议和格式访问远程存储 Linux 中有两种主要协议可用访问网络文件系统 : NFS 和CIFS 。 访问网络共享的三个…

最新机器学习开源项目Top10
作者 | Mybridge译者 | Linstancy整理 | Jane出品 | AI科技大本营【导读】过去一个月里,我们对近 1400 个机器学习项目进行了排名,并挑选出热度前 10 的项目。这份清单涵盖了包括 OpenAI 最新开发的 RND 算法、Uber 构建的第一个自然语言处理平台、由 Be…

linux批处理mysql数据库_使用批处理对MySQL进行数据批量操作
批处理是一种非交互式运行MySQL程序的方法,如同您在MySQL中使用的命令一样,你仍然将使用这些命令。为了实现批处理,您重定向一个文件到MySQL程序中,首先我们需要一个文本文件,这个文本文件包含有与我们在MySQL中输入的…

JDBC Driver常用连接方法列表
Microsoft SQL Server series (6.5, 7.x and 2000) and Sybase 10JDBC Name: jTDSURL: [url]http://jtds.sourceforge.net/[/url]Version: 0.5.1Download URL: [url]http://sourceforge.net/project/show...?group_id33291[/url]语法: Class.forName("net.sourceforge.jt…

C#强化系列文章四:匿名方法的使用
匿名方法相信很多人都听过,它是C#2.0的一个新特性,顾名思义,匿名方法就是没有名称的方法。那么在C#中的匿名方法有哪些好处,在C#中如何使用呢?匿名方法最明显的好处就是可以降低另写一个方法的工作量,另外一…

AI人才抢夺“生猛”: 应届博士年薪涨到80万元
作者 | 王玉凤来源 | 本文授权转自第一财经人工智能(AI)人才薪水之高、涨幅之大,颇有令人瞠目结舌之感。一年前,针对AI领域的应届毕业生,硕士生约莫能拿到30万元的年薪,博士生则高达50万元。今年࿰…

mysql的表空间是否自动扩展_Oracle修改指定表空间为自动扩展
1.数据文件自动扩展的好处1)不会出现因为没有剩余空间可以利用到数据无法写入2)尽量减少人为的维护3)可以用于重要级别不是很大的数据库中,如测试数据库等2.数据文件自动扩展的弊端1)如果任其扩大,在数据量不断变大的过程中会导致某个数据文件异常的大2)…

3.15好水指数N1能否让饮水健康不失控?
题记:3.15晚会曾曝光碱性水无益健康,过度饮用对人体有害。但现在市场上仍然有企业打着“碱性水有益健康”的招牌做营销,其居心何在呢?饮用水指数N1和中国优水地图在3.15这天正式发布,它们能对我们的饮水健康产生多大的影响? 凯文…

【iOS-cocos2d-X 游戏开发之十四】cocos2dx(c++)中访问object函数
Cocos2dx系列博文的上一篇详细介绍了如何在Xcode中利用jni调用Android的Java层代码,还没有看过的童鞋,请移步到如下博文: 【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用…

mysql实验报告四_实验报告四
实 实 验 报 告 课程名称 数据库实验及课程设计 实验项目 数据查询 实验 仪器 ___________________________ 系 别______信息管理学院______ 专 业________ ____________ 班级/ / 学号_ _ 学生姓名 _____ _____________ 实验日期 成 绩 _______________________ 指导教师 施永香…

京东数科业务架构全披露,陈生强发布城市操作系统和京东钼媒
11 月 20 日,在 JDD-2018 京东数字全球探索者大会上,陈生强宣布,京东数字科技(JD Digits)正式成为京东金融的母品牌,这也意味着它的业务架构逐渐明晰,主要下设了京东金融、京东城市、京东农牧、…

自动化测试十大要点
当一款自动化测试工具引入到一个项目中,我们通常对它给予很高的期望;项目成员希望工具能够尽可能的缩小测试范围、节约成本并缩短项目进度,然而可悲的是,很多采用自动化测试的项目依然失败了。 以下几个方面严重影响着自动化测试的…

DataGridView取得或者修改当前单元格的内容
当前单元格指的是DataGridView 焦点所在的单元格,它可以通过DataGridView 对象的CurrentCell 属性取得。如果当前单元格不存在的时候,返回Nothing(C#是null) [VB.NET] 取得当前单元格内容Console.WriteLine(DataGridView1.CurrentCell.Value) 取得当前单…

名图怎么弄云服务器_云服务器购买了宽带的速度怎么测试?
西昆云详细说一下企业租用云服务器搭建网站,很多新手站长会把带宽当成宽带来测试,比如在自己的云服务器上下载东西测试速度,一旦下载的东西慢了就觉得有问题,其实这是不准确的,那么如何查看云服务器的带宽速度呢&#…

ERP实施注意方面
一 厂商方面 1.信息化产品本身的功能需要强大而且灵活,应当能够指导企业管理水平的提升并适应企业的不同管理需要 2.厂商实力雄厚,人员稳定,服务周到,EPR 是个长期合作的过程 二 企业自身方面 1.企业自身管理意识,对ER…

一文回顾2018英特尔人工智能大会
近几日,整个 AI 行业的目光都聚焦在了北京。因为,一场人工智能盛会来了——2018 英特尔人工智能大会。逾千名国内外人工智能领域有影响力的专家、开发者、研究人员以及英特尔的客户和合作伙伴相聚在这里,共同探讨和分享人工智能领域的前沿技术…

用python写希尔排序_python希尔排序介绍(实例)
希尔排序介绍希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本,该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依…

【No.5 类型转换导致的错误】
【注意】 程序语言只是我们与计算机交流并让计算机实现我们创造性思想的工具,可以并鼓励深入掌握一门语言,但千万别沉迷于钻某种语言的牛角尖,一定要把握好二者间的度本帖属不定时连载贴,以试卷的形式提出一个比较基础的问题供大家…

小学AI教材终于来了,下一步是AI胎教吗?
小学生终于也要学 AI 了!据澎湃新闻报道,全国首套涵盖了从小学到高中的人工智能教材近日在上海正式发布,这套“AI上未来智造者”丛书计划出版 10 册,目前已出版 6 册,分别为《AI上神奇动物》、《AI上智慧生活》《AI在变…

快过年了,博客园里的文章也变少了
快过年了,博客园里的文章也变少了,大家都开始休息了吗?转载于:https://www.cnblogs.com/RobotTech/archive/2008/02/03/1063461.html