pivot.md 3.5 KB
Newer Older
M
Mars Liu 已提交
1 2 3 4
# 透视表

现有销售记录表

M
Mars Liu 已提交
5
```mysql
M
Mars Liu 已提交
6 7 8
create table sales(
    id serial primary key ,
    sku_id integer not null ,
M
Mars Liu 已提交
9
    amount decimal(12, 4),
M
Mars Liu 已提交
10 11 12 13 14 15 16
    created_at timestamp default now()
);
create index on sales(created_at);
```

现在我们希望对这个表做一个月度的透视汇总,得到2020年每个月每种商品(sku_id)的的销售总额,每个月一列,哪一项可以实现?

M
Mars Liu 已提交
17 18
<hr/>

M
Mars Liu 已提交
19
点击进入[MySQL实战练习环境](https://mydev.csdn.net/product/pod/new?image=cimg-centos7-skilltreemysql&connect=auto&create=auto&utm_source=skill)
F
feilong 已提交
20

M
Mars Liu 已提交
21 22
* `show databases` 列出所有数据库
* `show tables` 列出所有表
M
Mars Liu 已提交
23

M
Mars Liu 已提交
24 25
## 答案

M
Mars Liu 已提交
26
```mysql
M
Mars Liu 已提交
27
select sku_id, 
M
Mars Liu 已提交
28 29 30 31 32 33 34 35 36 37 38 39
       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 end) as Feb,
       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 end) as Apr,
       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 end) as June,
       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 end) as Aug,
       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 end) as Oct,
       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 end) as Dec
M
Mars Liu 已提交
40 41 42 43 44 45 46 47 48
from sales
where created_at between '2020-01-01'::timestamp and '2021-01-01'::timestamp
group by sku_id; 
```

## 选项

### 格式不相符

M
Mars Liu 已提交
49
```mysql
M
Mars Liu 已提交
50 51 52 53 54 55 56 57
select sku_id, extract(month from created_at) as month, sum(amount) 
from sales
where created_at between '2020-01-01'::timestamp and '2021-01-01'::timestamp
group by 1, 2; 
```

### 计算逻辑错误

M
Mars Liu 已提交
58
```mysql
M
Mars Liu 已提交
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
select sku_id, 
       sum(amount) as Jan,
       sum(amount) as Feb,
       sum(amount) as Mar,
       sum(amount) as Apr,
       sum(amount) as May,
       sum(amount) as June,
       sum(amount) as July,
       sum(amount) as Aug,
       sum(amount) as Sept,
       sum(amount) as Oct,
       sum(amount) as Nov,
       sum(amount) as Dec
from sales
where created_at between '2020-01-01'::timestamp and '2021-01-01'::timestamp
group by sku_id, extract(month from created_at); 
```

### 计算格式错误

M
Mars Liu 已提交
79
```mysql
M
Mars Liu 已提交
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
select sku_id, 
       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) = 3) as Mar,
       sum(amount having extract(month from created_at) = 4) as Apr,
       sum(amount having extract(month from created_at) = 5) as May,
       sum(amount having extract(month from created_at) = 6) as June,
       sum(amount having extract(month from created_at) = 7) as July,
       sum(amount having extract(month from created_at) = 8) as Aug,
       sum(amount having extract(month from created_at) = 9) as Sept,
       sum(amount having extract(month from created_at) = 10) as Oct,
       sum(amount having extract(month from created_at) = 11) as Nov,
       sum(amount having extract(month from created_at) = 12) as Dec
from sales
where created_at between '2020-01-01'::timestamp and '2021-01-01'::timestamp
group by sku_id, extract(month from created_at); 
```