mash笔记(基础SQL)4-6章

列属性

Datatype 注意CHAR(50)可能会浪费空间,一般使用VARCHAR(50)
PK主键 识别唯一
NN 打勾表示不能有空值
AI 自动递增,通常用在主键列:每次在表中插入一条新纪录,就是让MySQL或者数据库引擎在列中插入一个值,即在最后一行加入一个顾客(如果PK是customer_id)
会在加入新纪录的同时,将顾客id增加1

插入单行

INSERT INTO customers
VALUES (DEFAULT, 'John', 'Smith', '1990-01-01',NULL, 'address', 'city', 'CA', NULL)

NULL也可以用DEFAULT替代。

也可以不用DEFAULT或NULL,即在INSERT INTO customers 后打出需要赋值的列名,忽略NULL值的

INSERT INTO customers (
first_name,
last_name,
birth_date,
address,
city,
state)
VALUES (DEFAULT, 'John', 'Smith', '1990-01-01', 'address', 'city', 'CA')

插入多行

INSERT INTO shippers (name)
VALUES ('Shipper1'),
('Shipper2'),
('Shipper3')

分层插入

一个order id对应多个单子
INSERT INTO oredrs (customer_id, price)
VALUES(1, 2.23)

INSERT INTO order_items
VALUES
(LAST_INSERT_ID(), 1

创建表复制

CREATE TABLE orders_archived AS
SELECT * FROM orders
之后刷新,创建的表就会显示
创建了名为orders_archived的表,内容与orders表相同
删除表:右键truncat table

只复制一部分:
INSERT INTO orders_archived #如果前面没有创建过一个空的orders列名的空表,就在后面加上(列名)
SELECT *
FROM orders
WHERE order_date < '2019-01-01'

更新单行

UPDATE invoices
SET payment_total = 10, payment_data = '2019-03-01' #要设置进去的内容
WHERE invoice_id = 1

Updates中用子查询

UPDATE invoices
SET payment_total = invoice_total * 0.5,
payment_data = due_date
WHERE client_id =
(SELECT client_id
FROM clients
WHERE name = 'Myworks')

先运行括号内的内容,选出name为Myworks的行的client_id,对这些id对应的部分update

---多个id
UPDATE invoices
SET payment_total = invoice_total * 0.5,
payment_data = due_date
WHERE client_id IN
(SELECT client_id
FROM clients
WHERE state IN ('CA', 'NY'))

删除行

DELETE FROM invoices
WHERE invoice_id = 1

--
DELETE FROM invoices
WHERE client_id =
(SELECT client_id
FROM clients
WHERE name = 'Myworks')

恢复数据库

在MySQL工作台找到file菜单,打开SQL脚本,打开creat-databases执行

第五章

聚合函数

SELECT
MAX(invoice_total) AS highest,
MIN(invoice_total) AS lowest,
AVG(invoice_total) AS average
SUM((invoice_total) AS total,
COUNT(invoice_total) AS number_of_invoices,
COUNT(payment_total) AS count_of_payments,
SUM(invoice_total * 1.1) AS total,
COUNT(DISTINCT client_id) AS total_records
FROM invoices
WHERE invoice_date > '2019-07-01'

--
SELECT
'First half of 2019' AS date_range,
SUM(invoice_total) AS total_sales,
SUM(payment_total) AS total_payments,
SUM(invoice_total - payment_total) AS what_we_expect
FROM invoices
WHERE invoice_date
BETWEEN '2019-01-01' AND '2019-06-30'
UNION
SELECT
'Second half of 2019' AS date_range,
SUM(invoice_total) AS total_sales,
SUM(payment_total) AS total_payments,
SUM(invoice_total - payment_total) AS what_we_expect
FROM invoices
WHERE invoice_date
BETWEEN '2019-07-01' AND '2019-12-31'
UNION
SELECT
'Total' AS date_range,
SUM(invoice_total) AS total_sales,
SUM(payment_total) AS total_payments,
SUM(invoice_total - payment_total) AS what_we_expect
FROM invoices
WHERE invoice_date
BETWEEN '2019-09-01' AND '2019-06-30'

GROUP BY句子

根据client_id分组求和:
SELECT
client_id
SUM(invoice_total) AS total_sales
FROM invoices
GROUP BY client_id #根据client_id进行分组
ORDER BY total_sales DESC #降序排序

如果需要插入WHERE:
SELECT
client_id
SUM(invoice_total) AS total_sales
FROM invoices
WHERE invoice_date >= '2019-07-01'
GROUP BY client_id #根据client_id进行分组
ORDER BY total_sales DESC #降序排序

根据多列分组:
SELECT
state,
city,
SUM(invoice_total) AS total_sales
FROM invoices i
JOIN clients USING (client_id)
GROUP BY state, city


图片.png

--
SELECT
date,
pm.name AS payment_method,
SUM(amount) AS total_payments
FROM payments p
JOIN payment_methods pm
ON p.payment_method = pm.payment_method_id

关联两个表

GROUP BY date, payment_method
ORDER BY date

HAVING子句-筛选

SELECT
client_id,
SUM(invoice_total) AS total_sales,
COUNT(*) AS numeber_of_invoices
FROM invoices
GROUP BY client_id
HAVING total_sales > 500 AND number_of_invoice

(与WHERE的区别,HAVING在分组之后,WHERE在分组之后;WHERE可以筛选没有选择的列,HAVING只能筛选选择的列)

SELECT
c.customer_id,
c.first_name,
c.last_name,
SUM(oi.quantity * oi.unit_price) AS total_sales
FROM customers c
JOIN orders o USING (customer_id)
JOIN order_items oi USING (order_id)
WHERE state = 'VA'
GROUP BY
c.customer_id,
c.first_name,
c.last_name
HAVING total_sales > 100

ROLL UP运算符

对每一组的总计做了计算
SELECT
client_id,
SUM(invoice_total) AS total_sales
FROM invoices
GROUP BY client_id WITH ROLLUP

--
SELECT
payment_method,
SUM(amount) AS total
FROM payments
JOIN payment_methods pm
ON p.payment_method = pm.payment_method_id
GROUP BY payment_method WITH ROLLUP


图片.png

第六章

Subqueries

SELECT *
FROM products
WHERE unit_price > (
SELECT unit_price
FROM products
WHERE product_id = 3
)

IN运算符

SELECT *
FROM products
WHERE product_id NOT IN (
SELECT DISTINCT product_id
FROM order_items
)


唯一一个从来没有订购过的产品

SELECT *
FROM clients
WHERE client_id NOT IN (
SELECT DISTINCT client_id
FROM invoices
)

子查询vs连接

oi里没有customer_id,在子查询里先连接orders表

SELECT customer_id, last_name, first_name
FROM customers
WHERE customer_id IN (
SELECT o.customer_id
FROM order_items oi
JOIN orders o USING (order_id)
WHERE product_id = 3
) #得到购买3号产品的顾客


图片.png

与下面的连接语法结果一样:
SELECT DISTINCT customer_id, last_name, first_name
FROM customers c
JOIN orders o USING (customer_id)
JOIN order_items oi USING (order_id)
WHERE oi.product_id = 3

图片.png

第二种方法更加清晰

ALL关键字

USE sql_invoicing;

SELECT *
FROM invoices
WHERE invoice_total > (
SELECT MAX(invoice_total)
FROM invoices
WHERE client_id = 3
) #得到大于客户3所有发票额(客户3的最大发票额)的发票

图片.png

与以下方法相等:
SELECT *
FROM invoices
WHERE invoice_total > ALL (
SELECT invoice_total
FROM invoices
WHERE client_id = 3
)

ALL关键字的都可以用MAX改写

ANY关键字

SELECT *
FROM clients
WHERE client_id IN (
SELECT client_id
FROM invoices
GROUP BY client_id
HAVING COUNT(*) >= 2
)

等于:
SELECT *
FROM clients
WHERE client_id = ANY (
SELECT client_id
FROM invoices
GROUP BY client_id
HAVING COUNT(*) >= 2
)

也就是说IN与=ANY的效果是一样的

Correlated Subqueries 相关子查询

--for each employee
-- calculate the avg salary for emplyee.office
-- return the employee if salary > avg
SELECT *
FROM employees e
WHERE salary > (
SELECT AVG(salary)
FROM employees
WHERE office_id = e.office_id #不想计算所有员工的平均工资,加上筛选,只面向在同一个部门的员工
)
对每个员工执行子查询,因此e.office_id是每次这个员工所在的部门的id,所以平均的是这个部门的工资

EXISTS运算符

SELECT *
FROM clients c
WHERE EXISTS (
SELECT client_id
FROM invoices
WHERE client_id = c.client_id
)
等于:
SELECT *
FROM clients
WHERE client_id IN (
SELECT clinet_id
FROM invoices
)
--
SELECT *
FROM products p
WHERE NOT EXISTS (
SELECT product_id
FROM order_items
WHERE product_id = p.product_id
)

SELECT子句中的子查询

SELECT
invoice_id,
invoice_total,
(SELECT AVG(invoice_total)
FROM invoices) AS invoice_average,
invoice_total - (SELECT invoice_average)
FRROM invoices

FROM子句中的子查询

SELECT *
FROM (
SELECT
client_id,
name,
(SELECT SUM(invoice_total)
FROM invoices
WHERE client_id = c.client_id) AS total_sales
(SELECT AVG(invoice_total) FROM invoices) AS average
(SELECT total_sales - avergae) AS difference
FROM clients c
) AS sales_summary
WHERE total_sales IS NOT NULL

在选择语句的FROM子句中使用子查询的例子

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容