提交 cb34344a 编写于 作者: M Mars Liu

transaction

上级 3e4651af
...@@ -8,7 +8,7 @@ create table orders ( ...@@ -8,7 +8,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4) price decimal(12, 4)
); );
``` ```
...@@ -22,7 +22,7 @@ create table orders ( ...@@ -22,7 +22,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
ts timestamp default now() ts timestamp default now()
); );
``` ```
...@@ -37,7 +37,7 @@ create table orders ( ...@@ -37,7 +37,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
ts varchar(16) default now() ts varchar(16) default now()
); );
``` ```
...@@ -50,7 +50,7 @@ create table orders ( ...@@ -50,7 +50,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
ts varchar(16) format 'yyyy-mm-dd' ts varchar(16) format 'yyyy-mm-dd'
); );
``` ```
...@@ -63,7 +63,7 @@ create table orders ( ...@@ -63,7 +63,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
ts date default now() ts date default now()
); );
``` ```
...@@ -76,7 +76,7 @@ create table orders ( ...@@ -76,7 +76,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
ts datetime default now() ts datetime default now()
); );
``` ```
...@@ -8,7 +8,7 @@ create table orders ( ...@@ -8,7 +8,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
ts timestamp default now() ts timestamp default now()
); );
``` ```
...@@ -23,7 +23,7 @@ create table orders ( ...@@ -23,7 +23,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(2000), description varchar(2000),
ts timestamp default now() ts timestamp default now()
); );
...@@ -39,7 +39,7 @@ create table orders ( ...@@ -39,7 +39,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description char(2000), description char(2000),
ts timestamp default now() ts timestamp default now()
); );
...@@ -53,7 +53,7 @@ create table orders ( ...@@ -53,7 +53,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(256) default '', description varchar(256) default '',
ts timestamp default now() ts timestamp default now()
); );
...@@ -67,7 +67,7 @@ create table orders ( ...@@ -67,7 +67,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description text(2000), description text(2000),
ts timestamp default now() ts timestamp default now()
); );
...@@ -81,7 +81,7 @@ create table orders ( ...@@ -81,7 +81,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description tinytext(2000), description tinytext(2000),
ts timestamp default now() ts timestamp default now()
); );
......
...@@ -8,7 +8,7 @@ create table orders ( ...@@ -8,7 +8,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(2000), description varchar(2000),
ts timestamp default now() ts timestamp default now()
); );
...@@ -24,7 +24,7 @@ create table orders ( ...@@ -24,7 +24,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(2000), description varchar(2000),
picture blob, picture blob,
ts timestamp default now() ts timestamp default now()
...@@ -41,7 +41,7 @@ create table orders ( ...@@ -41,7 +41,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(2000), description varchar(2000),
picture varchar(100000), picture varchar(100000),
ts timestamp default now() ts timestamp default now()
...@@ -56,7 +56,7 @@ create table orders ( ...@@ -56,7 +56,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(2000), description varchar(2000),
picture text, picture text,
ts timestamp default now() ts timestamp default now()
...@@ -71,7 +71,7 @@ create table orders ( ...@@ -71,7 +71,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(2000), description varchar(2000),
picture binary(100000), picture binary(100000),
ts timestamp default now() ts timestamp default now()
...@@ -86,7 +86,7 @@ create table orders ( ...@@ -86,7 +86,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(2000), description varchar(2000),
picture varbinary(100000), picture varbinary(100000),
ts timestamp default now() ts timestamp default now()
......
...@@ -8,7 +8,7 @@ create table orders ( ...@@ -8,7 +8,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(2000), description varchar(2000),
ts timestamp default now(), ts timestamp default now(),
deal bool default false deal bool default false
...@@ -57,7 +57,7 @@ create table if not exists orders ( ...@@ -57,7 +57,7 @@ create table if not exists orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(2000), description varchar(2000),
ts timestamp default now(), ts timestamp default now(),
deal bool default false deal bool default false
......
...@@ -9,7 +9,7 @@ create table orders ...@@ -9,7 +9,7 @@ create table orders
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), price decimal(12, 4),
description varchar(2000), description varchar(2000),
ts timestamp default now(), ts timestamp default now(),
deal bool default false deal bool default false
......
...@@ -2,18 +2,17 @@ ...@@ -2,18 +2,17 @@
SmartMarket 公司的OA数据库中包含以下结构: SmartMarket 公司的OA数据库中包含以下结构:
```postgresql ```mysql
create table employee( create table employee(
id serial primary key , id serial primary key ,
name text, name varchar(256),
dept text, dept varchar(256),
salary money, salary decimal(12, 4)
meta jsonb default '{}'::jsonb
); );
create table budget( create table budget(
id serial primary key , id serial primary key ,
dept text, dept varchar(256),
amount money amount money
) )
``` ```
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
"node_id": "mysql-ac3c072bc54749bdb82324f2b203890d", "node_id": "mysql-ac3c072bc54749bdb82324f2b203890d",
"keywords": [], "keywords": [],
"children": [], "children": [],
"export": [], "export": [
"count.json"
],
"keywords_must": [], "keywords_must": [],
"keywords_forbid": [], "keywords_forbid": [],
"group": 0 "group": 0
......
{ {
"type": "code_options", "type": "code_options",
"author": "ccat", "author": "ccat",
"source": "daily_payment_2.md", "source": "count.md",
"notebook_enable": false, "notebook_enable": false,
"exercise_id": "ffde3c073ee848a093c5edc733c7a61c" "exercise_id": "550bc91b4d7849ef8463a807871d145c"
} }
\ No newline at end of file
# count 练习
Joe 建立了一个名为items的表
```
mysql> select * from items;
+----+-----------+
| id | item |
+----+-----------+
| 1 | 2 |
| 2 | NULL |
| 3 | 9 |
| 4 | 534214123 |
+----+-----------+
```
当他执行
```mysql
select count(*), count(item) from items;
```
会得到什么结果?
## 答案
```
3, 4
```
## 选项
### A
```
4, NULL
```
### B
```
3, 3
```
### C
```
1, 0
```
### D
```
NULL, NULL
```
### E
```
4, 4
```
\ No newline at end of file
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
"node_id": "mysql-c5654c150993418a96f692496837fbb7", "node_id": "mysql-c5654c150993418a96f692496837fbb7",
"keywords": [], "keywords": [],
"children": [], "children": [],
"export": [], "export": [
"sum.json"
],
"keywords_must": [], "keywords_must": [],
"keywords_forbid": [], "keywords_forbid": [],
"group": 0 "group": 0
......
{
"type": "code_options",
"author": "ccat",
"source": "sum.md",
"notebook_enable": false,
"exercise_id": "6ac9bb99a6684023ad80fde36ea32f6a"
}
\ No newline at end of file
# 求和练习
Joe 想要得到 orders 表
```mysql
create table orders (
id int primary key auto_increment,
item_id int,
amount int,
unit_price decimal(12, 4),
total decimal(12, 4),
description varchar(2000),
ts timestamp default now(),
deal bool default false
);
```
中所有单价(unit_price)超过 1000 的订单中,已成交(deal 为 true)的总值(total),这个查询应该是:
## 答案
```mysql
select sum(total) from orders where deal and unit_price > 1000;
```
## 选项
### A
```mysql
select sum(total) from orders where deal and unit_price > 1000;
```
### B
```mysql
select sum(total) from orders having deal and unit_price > 1000;
```
### C
```mysql
select sum(total) from orders group by deal having unit_price > 1000;
```
### D
```mysql
select sum(total) from orders having deal and unit_price > 1000;
```
\ No newline at end of file
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
"node_id": "mysql-c1652108441c424197c0c3c526e4831c", "node_id": "mysql-c1652108441c424197c0c3c526e4831c",
"keywords": [], "keywords": [],
"children": [], "children": [],
"export": [], "export": [
"min.json"
],
"keywords_must": [], "keywords_must": [],
"keywords_forbid": [], "keywords_forbid": [],
"group": 0 "group": 0
......
{
"type": "code_options",
"author": "ccat",
"source": "min.md",
"notebook_enable": false,
"exercise_id": "c25658691a9043eab38b61aec9ad827c"
}
\ No newline at end of file
# 最小值练习
Joe 想要得到 employee 表
```mysql
create table employee
(
id serial primary key,
name varchar(256),
dept varchar(256),
salary decimal(12, 4)
);
```
中每个部门工资最低的员工的工资信息,这条查询应该怎么写?
## 答案
```mysql
select dept, min(salary) from employee group by dept;
```
## 选项
### A
```mysql
select dept, min(salary) from employee;
```
### B
```mysql
select dept, min(salary) from employee;
```
### C
```mysql
select dept, min(salary) from employee;
```
### D
```mysql
select sum(total) from orders having deal and unit_price > 1000;
```
\ No newline at end of file
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
"node_id": "mysql-77042376726743bea5c97e82a67a2016", "node_id": "mysql-77042376726743bea5c97e82a67a2016",
"keywords": [], "keywords": [],
"children": [], "children": [],
"export": [], "export": [
"max.json"
],
"keywords_must": [], "keywords_must": [],
"keywords_forbid": [], "keywords_forbid": [],
"group": 0 "group": 0
......
{
"type": "code_options",
"author": "ccat",
"source": "max.md",
"notebook_enable": false,
"exercise_id": "7e56c3165ccc46f5b2ffb3d0eba53eff"
}
\ No newline at end of file
# 最大值练习
利用员工信息表:
```mysql
create table employee
(
id serial primary key,
name varchar(256),
dept varchar(256),
salary decimal(12, 4)
);
```
Joe 做了一些关于 max 函数的练习,其中不正确的是:
## 答案
```mysql
select id, dept, max(salary) as salary, name
from employee
group by dept
```
可以得到每个部门工资最高的员工的全部信息。
## 选项
### A
```mysql
select dept, max(salary) as salary
from employee
group by dept
```
可以得到每个部门的最高工资。
### B
```mysql
select max(salary) as salary
from employee
```
可以得到全部员工中最高的工资。
### C
```mysql
select dept, sum(salary)
from employee
group by dept
having max(salary) < 20000
```
可以得到员工最高工资不超过两万的部门及其总的工资开支
### D
```mysql
select dept, min(salary)
from employee
group by dept
having max(salary) > 50000
```
可以得到员工最高工资超过五万的部门,及其最低工资的清单
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
现有员工信息表如下: 现有员工信息表如下:
```postgresql ```mysql
create table employee create table employee
( (
id serial primary key, id serial primary key,
name text, name varchar(256),
dept text, dept varchar(256),
salary money salary money
); );
``` ```
...@@ -16,7 +16,7 @@ create table employee ...@@ -16,7 +16,7 @@ create table employee
## 答案 ## 答案
```postgresql ```mysql
select l.id, l.name, l.dept, l.salary select l.id, l.name, l.dept, l.salary
from employee as l from employee as l
join (select max(salary) as salary, dept join (select max(salary) as salary, dept
...@@ -29,7 +29,7 @@ from employee as l ...@@ -29,7 +29,7 @@ from employee as l
### select 与 group by 不匹配 ### select 与 group by 不匹配
```postgresql ```mysql
select id, name, dept, max(salary) select id, name, dept, max(salary)
from employee from employee
group by dept; group by dept;
...@@ -37,7 +37,7 @@ group by dept; ...@@ -37,7 +37,7 @@ group by dept;
### group by 不对 ### group by 不对
```postgresql ```mysql
select id, name, dept, max(salary) select id, name, dept, max(salary)
from employee from employee
group by dept, id, name; group by dept, id, name;
...@@ -45,7 +45,7 @@ group by dept, id, name; ...@@ -45,7 +45,7 @@ group by dept, id, name;
### group by 不对 ### group by 不对
```postgresql ```mysql
select id, name, dept, max(salary) select id, name, dept, max(salary)
from employee from employee
group by dept, id, name group by dept, id, name
...@@ -54,7 +54,7 @@ having salary = max(salary); ...@@ -54,7 +54,7 @@ having salary = max(salary);
### 结构错误 ### 结构错误
```postgresql ```mysql
select id, name, dept, max(salary) select id, name, dept, max(salary)
from employee from employee
where salary = max(salary) where salary = max(salary)
......
# 客户和订单 # 客户和订单
我们现在看下面这个客户/订单系统 Goods 中有客户/订单系统如下:
```postgresql ```mysql
create table customers create table customers
( (
id serial primary key, id serial primary key,
company_name text, company_name varchar(256),
address text, address varchar(1024),
city text, city varchar(256),
state text state varchar(256)
); );
create table products create table products
( (
id serial primary key, id serial primary key,
description text, description varchar(1024),
unit_price money unit_price decimal(12, 4)
); );
create table orders create table orders
......
{
"node_id": "mysql-f045eeff32bd449c83afc76abdd65344",
"keywords": [],
"children": [],
"export": [
"subquery.json"
],
"keywords_must": [],
"keywords_forbid": []
}
\ No newline at end of file
# 子查询
现有员工表
```mysql
create table employee
(
id serial primary key,
name varchar(256),
dept varchar(256),
salary decimal(12, 4)
);
```
Joe 希望找出比销售部(dept 为 sale)工资最高的员工工资更高的那部分人,查询出他们的完整信息,下面哪一项可以满足要求?
## 答案
```mysql
select id, name, dept, salary
from employee
where salary > (select max(salary)
from employee
where dept = 'sale')
```
## 选项
### A
```mysql
select id, name, dept, salary
from employee
where dept = 'sale'
group by dept
having salary > max(salary)
```
### B
```mysql
select l.id, l.name, l.dept, l.salary
from employee as l
join employee as r on l.salary > max(r.salary)
where r.dept = 'sale'
group by r.dept
```
### C
```mysql
select id, name, dept, salary
from employee
having salary > (select max(salary) from employee where dept = 'sale')
```
{ {
"node_id": "mysql-6bb279fa10fa4633a3af51ff7001f5ce", "node_id": "mysql-6bb279fa10fa4633a3af51ff7001f5ce",
"keywords": [], "keywords": ["subquery", "子查询", "any"],
"children": [], "children": [],
"export": [], "export": [],
"keywords_must": [], "keywords_must": [],
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
现有员工表 现有员工表
```postgresql ```mysql
create table employee create table employee
( (
id serial primary key, id int primary key auto_increment,
name text, name varchar(256),
dept text, dept varchar(256),
salary money salary decimal(12, 4)
) )
``` ```
...@@ -16,7 +16,7 @@ create table employee ...@@ -16,7 +16,7 @@ create table employee
## 答案 ## 答案
```postgresql ```mysql
select id, name, dept, salary select id, name, dept, salary
from employee from employee
where salary > (select max(salary) where salary > (select max(salary)
...@@ -28,7 +28,7 @@ where salary > (select max(salary) ...@@ -28,7 +28,7 @@ where salary > (select max(salary)
### A ### A
```postgresql ```mysql
select id, name, dept, salary select id, name, dept, salary
from employee from employee
where dept = 'sale' where dept = 'sale'
...@@ -38,7 +38,7 @@ having salary > max(salary) ...@@ -38,7 +38,7 @@ having salary > max(salary)
### B ### B
```postgresql ```mysql
select l.id, l.name, l.dept, l.salary select l.id, l.name, l.dept, l.salary
from employee as l from employee as l
join employee as r on l.salary > max(r.salary) join employee as r on l.salary > max(r.salary)
...@@ -48,7 +48,7 @@ group by r.dept ...@@ -48,7 +48,7 @@ group by r.dept
### C ### C
```postgresql ```mysql
select id, name, dept, salary select id, name, dept, salary
from employee from employee
having salary > (select max(salary) from employee where dept = 'sale') having salary > (select max(salary) from employee where dept = 'sale')
......
# 获取连续区间 # 获取连续区间
SmartMarket 交易所的系统中,所有订单在生成时,都从一个 PostgreSQL Sequence 中获取唯一的 序列号,完成交易计算后各个撮合程序将其插入如下的 orders 表中: SmartMarket 交易所的系统中,所有订单在生成时,都从一个 oracle Sequence 中获取唯一的
序列号,完成交易计算后各个撮合程序将其插入如下的 orders 表中:
```postgresql ```mysql
create table orders create table orders
( (
id integer primary key, id integer primary key,
meta jsonb default '{}'::jsonb, content json
content jsonb default '{}'::jsonb
-- ignore other definitions... -- ignore other definitions...
); );
``` ```
后续的结算系统需要连续的获取订单,以便处理一些顺序敏感的业务。但是撮合发生在很多个异步节点上,它们只能保证最终会将所有订单都保存到 orders 表,确保 id 列最终是连续的,但是最新插入的一段记录集有可能不连续。而我们希望结算系统成批 后续的结算系统需要连续的获取订单,以便处理一些顺序敏感的业务。但是撮合发生在很多个异步节
的读取数据,以优化性能,那么在结算系统有它最后处理的订单id的前提下,下面哪一个查询可以确保从这个id向前读取 id 连续 的一批订单? 点上,它们只能保证最终会将所有订单都保存到 orders 表,确保 id 列最终是连续的,但是最新
插入的一段记录集有可能不连续。而我们希望结算系统成批的读取数据,以优化性能,那么在结算系
统有它最后处理的订单id的前提下,下面哪一个查询可以确保从这个id向前读取 id 连续 的一批
订单?
## 答案 ## 答案
```postgresql ```mysql
with recursive r(id) as (select id with recursive r(id) as (select id
from orders from orders
where id = $1 where id = $1
...@@ -25,7 +28,7 @@ with recursive r(id) as (select id ...@@ -25,7 +28,7 @@ with recursive r(id) as (select id
select d.id select d.id
from orders as d from orders as d
join r on d.id = r.id + 1) join r on d.id = r.id + 1)
select orders.id, meta, content select orders.id, content
from orders from orders
join r on orders.id = r.id; join r on orders.id = r.id;
``` ```
...@@ -38,8 +41,8 @@ from orders ...@@ -38,8 +41,8 @@ from orders
### B ### B
```postgresql ```mysql
select data.id, meta, content select data.id, content
from orders from orders
join orders as r on orders.id = r.id - 1 join orders as r on orders.id = r.id - 1
where id = $1; where id = $1;
...@@ -47,15 +50,15 @@ where id = $1; ...@@ -47,15 +50,15 @@ where id = $1;
### C ### C
```postgresql ```mysql
select id, meta, content select id, content
from orders from orders
where id in (select id from orders where id = id + 1); where id in (select id from orders where id = id + 1);
``` ```
### D ### D
```postgresql ```mysql
with r as (select id with r as (select id
from orders from orders
where id = $1 where id = $1
...@@ -63,7 +66,7 @@ with r as (select id ...@@ -63,7 +66,7 @@ with r as (select id
select d.id select d.id
from orders as d from orders as d
join r on d.id = r.id + 1) join r on d.id = r.id + 1)
select orders.id, meta, content select orders.id, content
from orders from orders
join r on orders.id = r.id; join r on orders.id = r.id;
``` ```
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
现有员工信息表如下: 现有员工信息表如下:
```postgresql ```mysql
create table employee create table employee
( (
id serial primary key, id serial primary key,
...@@ -16,7 +16,7 @@ create table employee ...@@ -16,7 +16,7 @@ create table employee
## 答案 ## 答案
```postgresql ```mysql
select id, name, dept, salary select id, name, dept, salary
from (select id, name, dept, salary, rank() over (partition by dept order by salary desc) as r from (select id, name, dept, salary, rank() over (partition by dept order by salary desc) as r
from employee) as t from employee) as t
...@@ -27,7 +27,7 @@ where r <= 5; ...@@ -27,7 +27,7 @@ where r <= 5;
### 结构错误 ### 结构错误
```postgresql ```mysql
select id, name, dept, max(salary) as salary select id, name, dept, max(salary) as salary
from employee from employee
group by dept group by dept
...@@ -36,7 +36,7 @@ having id < 6; ...@@ -36,7 +36,7 @@ having id < 6;
### 结构错误 ### 结构错误
```postgresql ```mysql
select l.id, l.name, l.dept, l.salary select l.id, l.name, l.dept, l.salary
from employee as l from employee as l
join (select max(salary) as salary, dept join (select max(salary) as salary, dept
...@@ -48,7 +48,7 @@ where count(r.id) <= 5; ...@@ -48,7 +48,7 @@ where count(r.id) <= 5;
### 结构错误 ### 结构错误
```postgresql ```mysql
select l.id, l.name, l.dept, l.salary select l.id, l.name, l.dept, l.salary
from employee as l from employee as l
join (select max(salary, 5) as salary, dept join (select max(salary, 5) as salary, dept
...@@ -59,7 +59,7 @@ from employee as l ...@@ -59,7 +59,7 @@ from employee as l
### 结构错误 ### 结构错误
```postgresql ```mysql
select id, name, dept, salary, rank() over (partition by dept order by salary desc) as r select id, name, dept, salary, rank() over (partition by dept order by salary desc) as r
from employee from employee
where r <= 5; where r <= 5;
...@@ -67,7 +67,7 @@ where r <= 5; ...@@ -67,7 +67,7 @@ where r <= 5;
### 结构错误 ### 结构错误
```postgresql ```mysql
select id, name, dept, salary, rank() as r over (partition by dept order by salary desc) select id, name, dept, salary, rank() as r over (partition by dept order by salary desc)
from employee from employee
where r <= 5; where r <= 5;
......
...@@ -2,12 +2,11 @@ ...@@ -2,12 +2,11 @@
现有销售记录表 现有销售记录表
```postgresql ```mysql
create table sales( create table sales(
id serial primary key , id serial primary key ,
sku_id integer not null , sku_id integer not null ,
amount money, amount decimal(12, 4),
meta jsonb default '{}'::jsonb,
created_at timestamp default now() created_at timestamp default now()
); );
create index on sales(created_at); create index on sales(created_at);
...@@ -17,20 +16,20 @@ create index on sales(created_at); ...@@ -17,20 +16,20 @@ create index on sales(created_at);
## 答案 ## 答案
```postgresql ```mysql
select sku_id, select sku_id,
sum(case extract(month from created_at) when 1 then amount else 0::money end) as Jan, sum(case extract(month from created_at) when 1 then amount else 0 end) as Jan,
sum(case extract(month from created_at) when 2 then amount else 0::money end) as Feb, sum(case extract(month from created_at) when 2 then amount else 0 end) as Feb,
sum(case extract(month from created_at) when 3 then amount else 0::money end) as Mar, sum(case extract(month from created_at) when 3 then amount else 0 end) as Mar,
sum(case extract(month from created_at) when 4 then amount else 0::money end) as Apr, sum(case extract(month from created_at) when 4 then amount else 0 end) as Apr,
sum(case extract(month from created_at) when 5 then amount else 0::money end) as May, sum(case extract(month from created_at) when 5 then amount else 0 end) as May,
sum(case extract(month from created_at) when 6 then amount else 0::money end) as June, sum(case extract(month from created_at) when 6 then amount else 0 end) as June,
sum(case extract(month from created_at) when 7 then amount else 0::money end) as July, sum(case extract(month from created_at) when 7 then amount else 0 end) as July,
sum(case extract(month from created_at) when 8 then amount else 0::money end) as Aug, sum(case extract(month from created_at) when 8 then amount else 0 end) as Aug,
sum(case extract(month from created_at) when 9 then amount else 0::money end) as Sept, sum(case extract(month from created_at) when 9 then amount else 0 end) as Sept,
sum(case extract(month from created_at) when 10 then amount else 0::money end) as Oct, sum(case extract(month from created_at) when 10 then amount else 0 end) as Oct,
sum(case extract(month from created_at) when 11 then amount else 0::money end) as Nov, sum(case extract(month from created_at) when 11 then amount else 0 end) as Nov,
sum(case extract(month from created_at) when 12 then amount else 0::money end) as Dec sum(case extract(month from created_at) when 12 then amount else 0 end) as Dec
from sales from sales
where created_at between '2020-01-01'::timestamp and '2021-01-01'::timestamp where created_at between '2020-01-01'::timestamp and '2021-01-01'::timestamp
group by sku_id; group by sku_id;
...@@ -40,7 +39,7 @@ group by sku_id; ...@@ -40,7 +39,7 @@ group by sku_id;
### 格式不相符 ### 格式不相符
```postgresql ```mysql
select sku_id, extract(month from created_at) as month, sum(amount) select sku_id, extract(month from created_at) as month, sum(amount)
from sales from sales
where created_at between '2020-01-01'::timestamp and '2021-01-01'::timestamp where created_at between '2020-01-01'::timestamp and '2021-01-01'::timestamp
...@@ -49,7 +48,7 @@ group by 1, 2; ...@@ -49,7 +48,7 @@ group by 1, 2;
### 计算逻辑错误 ### 计算逻辑错误
```postgresql ```mysql
select sku_id, select sku_id,
sum(amount) as Jan, sum(amount) as Jan,
sum(amount) as Feb, sum(amount) as Feb,
...@@ -70,7 +69,7 @@ group by sku_id, extract(month from created_at); ...@@ -70,7 +69,7 @@ group by sku_id, extract(month from created_at);
### 计算格式错误 ### 计算格式错误
```postgresql ```mysql
select sku_id, select sku_id,
sum(amount having extract(month from created_at) = 1) as Jan, sum(amount having extract(month from created_at) = 1) as Jan,
sum(amount having extract(month from created_at) = 2) as Feb, sum(amount having extract(month from created_at) = 2) as Feb,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
现有一个表 现有一个表
```postgresql ```mysql
create table book_in( create table book_in(
login integer primary key , login integer primary key ,
score integer default 0 score integer default 0
...@@ -14,15 +14,15 @@ create table book_in( ...@@ -14,15 +14,15 @@ create table book_in(
## 答案 ## 答案
```postgresql ```mysql
insert into book_in(login, score) values ($1, $2) on conflict do update set score=$2; insert into book_in(login, score) values ($1, $2) on DUPLICATE KEY update score=$2;
``` ```
## 选项 ## 选项
### A ### A
```postgresql ```mysql
try try
insert into book_in(login, score) values ($1, $2); insert into book_in(login, score) values ($1, $2);
catch catch
...@@ -33,18 +33,18 @@ finally ...@@ -33,18 +33,18 @@ finally
### B ### B
```postgresql ```mysql
insert into book_in(login, score) select $1, $2; insert into book_in(login, score) select $1, $2;
``` ```
### C ### C
```postgresql ```mysql
replace book_in(login, score) select $1, $2; replace book_in(login, score) select $1, $2;
``` ```
### D ### D
```postgresql ```mysql
upsert into book_in(login, score) select $1, $2; upsert into book_in(login, score) select $1, $2;
``` ```
...@@ -2,27 +2,32 @@ ...@@ -2,27 +2,32 @@
现有 test1 表如下 现有 test1 表如下
```postgresql ```mysql
create table test1(a integer primary key ); create table test1(a integer primary key );
``` ```
我们执行下面的语句 我们执行下面的语句
```postgresql ```mysql
CREATE PROCEDURE transaction_test1() CREATE PROCEDURE transaction_test1()
LANGUAGE plpgsql
AS $$
BEGIN BEGIN
FOR i IN 0..9 LOOP declare idx int;
INSERT INTO test1 (a) VALUES (i); set idx = 0;
IF i % 2 = 0 THEN iter: LOOP
start transaction ;
INSERT INTO test1 (a) VALUES (idx);
IF (idx % 2) = 0 THEN
COMMIT; COMMIT;
ELSE ELSE
ROLLBACK; ROLLBACK;
END IF; END IF;
END LOOP; IF idx < 10 THEN
set idx = idx + 1;
ITERATE iter;
END IF;
LEAVE iter;
END LOOP iter;
END; END;
$$;
CALL transaction_test1(); CALL transaction_test1();
``` ```
...@@ -31,13 +36,13 @@ CALL transaction_test1(); ...@@ -31,13 +36,13 @@ CALL transaction_test1();
## 答案 ## 答案
每当循环迭代到偶数的时候提交插入,最终 test1 表中是`0,2,4,6,8` 每当循环迭代到偶数的时候提交插入,最终 test1 表中是`0,2,4,6,8,10`
## 选项 ## 选项
### A ### A
以最后一次提交为准,最终 test1 表中是 0 到 9 共九个数字。 以最后一次提交为准,最终 test1 表中是 0 到 10 共11个数字。
### B ### B
......
...@@ -8,8 +8,7 @@ ...@@ -8,8 +8,7 @@
], ],
"children": [], "children": [],
"export": [ "export": [
"daily_payment.json", "daily_payment.json"
"daily_payment_2.json"
], ],
"keywords_must": [ "keywords_must": [
"索引", "索引",
......
...@@ -2,27 +2,28 @@ ...@@ -2,27 +2,28 @@
数据分析组需要经常执行以下查询生成从昨天到之前某一天的交易量统计 数据分析组需要经常执行以下查询生成从昨天到之前某一天的交易量统计
```postgresql ```mysql
select payment_date::date as day, sum(amount) select date(payment_date) as day, sum(amount)
from payment from payment
where (payment_date::date) between $1 and 'yesterday'::date where date(payment_date) between $1 and DATE_SUB(CURDATE(), INTERVAL 1 DAY)
group by payment_date::date; group by date(payment_date);
``` ```
现在这个查询很慢,payment 表的信息如下: 现在这个查询很慢,payment 表的信息如下:
```text ```text
Table "public.payment" mysql> desc payment;
Column | Type | Collation | Nullable | Default +---------------+---------------+------+-----+---------+----------------+
--------------+-----------------------------+-----------+----------+--------------------------------------------- | Field | Type | Null | Key | Default | Extra |
payment_id | integer | | not null | nextval('payment_payment_id_seq'::regclass) +---------------+---------------+------+-----+---------+----------------+
customer_id | smallint | | not null | | payment_id | int | NO | PRI | NULL | auto_increment |
staff_id | smallint | | not null | | customer_id | int | YES | | NULL | |
rental_id | integer | | not null | | staff_id | int | YES | | NULL | |
amount | numeric(5,2) | | not null | | rental_id | int | YES | | NULL | |
payment_date | timestamp without time zone | | not null | | amount | decimal(12,8) | YES | | NULL | |
Indexes: | pathment_date | timestamp | YES | | NULL | |
"payment_pkey" PRIMARY KEY, btree (payment_id) +---------------+---------------+------+-----+---------+----------------+
6 rows in set (0.12 sec)
``` ```
应该如何优化这个查询? 应该如何优化这个查询?
...@@ -31,8 +32,8 @@ Indexes: ...@@ -31,8 +32,8 @@ Indexes:
建立表达式索引 建立表达式索引
```postgresql ```mysql
create index on payment((payment_date::date)); alter table payment add index idx_payment_date((date(payment_date)));
``` ```
## 选项 ## 选项
...@@ -41,16 +42,16 @@ create index on payment((payment_date::date)); ...@@ -41,16 +42,16 @@ create index on payment((payment_date::date));
建立视图 建立视图
```postgresql ```mysql
create view view_daily_payment as select payment_date::date as day, amount from payment; create view view_daily_payment as select date(payment_date) as day, amount from payment;
``` ```
然后在视图 view_daily_payment 上执行 然后在视图 view_daily_payment 上执行
```postgresql ```mysql
select day, sum(amount) select day, sum(amount)
from view_daily_payment from view_daily_payment
where day between $1 and 'yesterday'::date where day between $1 and DATE_SUB(CURDATE(), INTERVAL 1 DAY)
group by day group by day
``` ```
...@@ -58,23 +59,23 @@ group by day ...@@ -58,23 +59,23 @@ group by day
在 payment_date 列上建立索引 在 payment_date 列上建立索引
```postgresql ```mysql
create index on payment(payment_date); create index idx_payment_date on payment(payment_date);
``` ```
### 可以简化语句,但对优化没有帮助 ### 可以简化语句,但对优化没有帮助
建立计算列 建立计算列
```postgresql ```mysql
alter table payment add day date generated always as ( payment_date::date ) stored alter table payment add day date generated always as (date(payment_date)) stored;
``` ```
然后使用它改写查询 然后使用它改写查询
```postgresql ```mysql
select day as day, sum(amount) select day as day, sum(amount)
from payment from payment
where day between $1 and 'yesterday'::date where day between $1 and date('yesterday')
group by day; group by day;
``` ```
\ No newline at end of file
# 每日报表优化
# 每日报表
统计过去一段时间的数据,你发现 payment 表上每天的订单量很大,下面这个查询的统计过程占用了大多数数据库资源,查询不会
早止当天,总是在历史上某一个日期段内查询
```postgresql
select payment_date::date as day, sum(amount)
from payment
where (payment_date::date) between $1 and $2
group by payment_date::date;
```
payment 表的信息如下:
```text
Table "public.payment"
Column | Type | Collation | Nullable | Default
--------------+-----------------------------+-----------+----------+---------------------------------------------
payment_id | integer | | not null | nextval('payment_payment_id_seq'::regclass)
customer_id | smallint | | not null |
staff_id | smallint | | not null |
rental_id | integer | | not null |
amount | numeric(5,2) | | not null |
payment_date | timestamp without time zone | | not null |
Indexes:
"payment_pkey" PRIMARY KEY, btree (payment_id)
```
怎样做是最有效的?
## 答案
建立物化视图并建立索引。
```postgresql
create materialized view view_daily_payment as
select payment_date::date as day, sum(amount) as amount from payment group by day;
create index on view_daily_payment(day);
```
使用
```postgresql
select day, amount from view_daily_payment where day between $1 and $2;
```
进行查询。并且每天定时执行一次刷新命令
```postgresql
REFRESH MATERIALIZED VIEW view_daily_payment;
```
## 选项
### 不会优化 sum 和 group by
在 payment_date 列上建立索引
```postgresql
create index on payment(payment_date);
```
### 不会优化 sum
建立计算列
```postgresql
alter table payment add day date generated always as ( payment_date::date ) stored
```
然后使用它改写查询
```postgresql
select day as day, sum(amount)
from payment
where day between $1 and 'yesterday'::date
group by day;
```
### 优化了日期查询,但是不会优化统计过程
建立表达式索引
```postgresql
create index on payment((payment_date::date));
```
### 不做物化,对查询速度不会有显著改善
建立视图
```postgresql
create view view_daily_payment as select payment_date::date as day, amount from payment;
```
然后在视图 view_daily_payment 上执行
```postgresql
select day, sum(amount)
from view_daily_payment
where day between $1 and 'yesterday'::date
group by day
```
\ No newline at end of file
...@@ -547,7 +547,11 @@ ...@@ -547,7 +547,11 @@
{ {
"CASE": { "CASE": {
"node_id": "mysql-8e6cd4d5f4b446a2bc3f5402de9bd49c", "node_id": "mysql-8e6cd4d5f4b446a2bc3f5402de9bd49c",
"keywords": [], "keywords": [
"case",
"pivot",
"透视表"
],
"children": [], "children": [],
"keywords_must": [], "keywords_must": [],
"keywords_forbid": [] "keywords_forbid": []
...@@ -803,7 +807,16 @@ ...@@ -803,7 +807,16 @@
], ],
"children": [ "children": [
{ {
"ANY": { "相关子查询": {
"node_id": "mysql-f045eeff32bd449c83afc76abdd65344",
"keywords": [],
"children": [],
"keywords_must": [],
"keywords_forbid": []
}
},
{
" ANY": {
"node_id": "mysql-6bb279fa10fa4633a3af51ff7001f5ce", "node_id": "mysql-6bb279fa10fa4633a3af51ff7001f5ce",
"keywords": [], "keywords": [],
"children": [], "children": [],
......
...@@ -3,7 +3,7 @@ create table orders ( ...@@ -3,7 +3,7 @@ create table orders (
item_id int, item_id int,
amount int, amount int,
unit_price decimal(12, 4), unit_price decimal(12, 4),
total_price decimal(12, 4), total decimal(12, 4),
description varchar(2000), description varchar(2000),
ts timestamp default now(), ts timestamp default now(),
deal bool default false deal bool default false
......
create table payment(
payment_id int primary key auto_increment,
customer_id int,
staff_id int,
rental_id int,
amount decimal(12, 8),
payment_date timestamp
)
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册