SQL select 并取数据作为列名
SQL select and take data as column name
我有一个存储如下记录的数据库:
+----+---------------------+-------------+-----------------+
| id | user_name | status| date |
+----+---------------------+-------------+-----------------+
| 1 | A | Paid| 2016-10-11|
| 2 | B | Not Paid| 2016-10-12|
| 3 | C | Paid| 2016-10-12|
| 4 | A | Not Paid| 2016-10-13|
+----+---------------------+-------------+-----------------+
我希望获得如下结果:
+----+---------------------+-------------+-----------------+-----------------+
| id | user_name | 2016-10-11| 2016-10-12 | 2016-10-13 |
+----+---------------------+-------------+-----------------+-----------------+
| 1 | A | Paid| NA| Not Paid|
| 2 | B | NA| Not Paid| NA|
| 3 | C | NA| Paid| Na|
+----+---------------------+-------------+-----------------+-----------------+
如何查询才能得到这样的结果?
PS:英语不好
仅供参考:我将 mySQL 用作 DBMS,这里是创建脚本:
CREATE TABLE `moneygame`.`pay_table`(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR(50),
`status` VARCHAR(50),
`p_date` DATE,
PRIMARY KEY (`id`)
);
您可以这样查询
select user_name, max([2016-10-11]) as [2016-10-11], max([2016-10-12]) [2016-10-12],max([2016-10-13]) [2016-10-13] from #yourtable
pivot
(max(status) for date in ([2016-10-11],[2016-10-12],[2016-10-13])) p
group by user_name
如果没有固定数量的日期,那么我不建议您做您正在尝试做的事情。无论如何,这就是问题的解决方案。
create table p as select * from
(select 1 id, 'A' user_name, 'Paid' status, '2016-10-11' date union
select 2 id, 'B' user_name, 'Not Paid' status, '2016-10-12' date union
select 3 id, 'C' user_name, 'Paid' status, '2016-10-12' date union
select 4 id, 'A' user_name, 'Not Paid' status, '2016-10-13' date) t;
When dates are represented as columns
select user_name, ifnull(max(a),'NA') `2016-10-11`,
ifnull(max(b),'NA') `2016-10-12`, ifnull(max(c),'NA') `2016-10-13`
from (select user_name,
case when date = '2016-10-11' then status else null end a,
case when date = '2016-10-12' then status else null end b,
case when date = '2016-10-13' then status else null end c
from p group by user_name, date) s group by user_name;
When user names are represented as columns
如果您有固定数量的用户和移动的日期范围,那么这样做应该是最佳选择。
select date, ifnull(max(a),'NA') A,
ifnull(max(b),'NA') B, ifnull(max(c),'NA') C from
(select date,
case when user_name = 'A' then status else null end a,
case when user_name = 'B' then status else null end b,
case when user_name = 'C' then status else null end c
from p group by date, user_name) x group by date;
顺便说一句,如果你还需要做动态列,你应该阅读这个:
- How to automate pivot tables in MySQL
- MySQL pivot into dynamic number of columns
我有一个存储如下记录的数据库:
+----+---------------------+-------------+-----------------+
| id | user_name | status| date |
+----+---------------------+-------------+-----------------+
| 1 | A | Paid| 2016-10-11|
| 2 | B | Not Paid| 2016-10-12|
| 3 | C | Paid| 2016-10-12|
| 4 | A | Not Paid| 2016-10-13|
+----+---------------------+-------------+-----------------+
我希望获得如下结果:
+----+---------------------+-------------+-----------------+-----------------+
| id | user_name | 2016-10-11| 2016-10-12 | 2016-10-13 |
+----+---------------------+-------------+-----------------+-----------------+
| 1 | A | Paid| NA| Not Paid|
| 2 | B | NA| Not Paid| NA|
| 3 | C | NA| Paid| Na|
+----+---------------------+-------------+-----------------+-----------------+
如何查询才能得到这样的结果?
PS:英语不好
仅供参考:我将 mySQL 用作 DBMS,这里是创建脚本:
CREATE TABLE `moneygame`.`pay_table`(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR(50),
`status` VARCHAR(50),
`p_date` DATE,
PRIMARY KEY (`id`)
);
您可以这样查询
select user_name, max([2016-10-11]) as [2016-10-11], max([2016-10-12]) [2016-10-12],max([2016-10-13]) [2016-10-13] from #yourtable
pivot
(max(status) for date in ([2016-10-11],[2016-10-12],[2016-10-13])) p
group by user_name
如果没有固定数量的日期,那么我不建议您做您正在尝试做的事情。无论如何,这就是问题的解决方案。
create table p as select * from
(select 1 id, 'A' user_name, 'Paid' status, '2016-10-11' date union
select 2 id, 'B' user_name, 'Not Paid' status, '2016-10-12' date union
select 3 id, 'C' user_name, 'Paid' status, '2016-10-12' date union
select 4 id, 'A' user_name, 'Not Paid' status, '2016-10-13' date) t;
When dates are represented as columns
select user_name, ifnull(max(a),'NA') `2016-10-11`,
ifnull(max(b),'NA') `2016-10-12`, ifnull(max(c),'NA') `2016-10-13`
from (select user_name,
case when date = '2016-10-11' then status else null end a,
case when date = '2016-10-12' then status else null end b,
case when date = '2016-10-13' then status else null end c
from p group by user_name, date) s group by user_name;
When user names are represented as columns
如果您有固定数量的用户和移动的日期范围,那么这样做应该是最佳选择。
select date, ifnull(max(a),'NA') A,
ifnull(max(b),'NA') B, ifnull(max(c),'NA') C from
(select date,
case when user_name = 'A' then status else null end a,
case when user_name = 'B' then status else null end b,
case when user_name = 'C' then status else null end c
from p group by date, user_name) x group by date;
顺便说一句,如果你还需要做动态列,你应该阅读这个:
- How to automate pivot tables in MySQL
- MySQL pivot into dynamic number of columns