在 Mysql 中调整 Table?
Pivot Table in Mysql?
嗨,我有一个动态 table 看起来像这样,
CREATE TABLE Table1
(`ID_Question` varchar(2), `ID_Solution` varchar(4), `ID_Mapping` int)
;
INSERT INTO Table1
(`ID_Question`, `ID_Solution`, `ID_Mapping`)
VALUES
('B1', 'GFC1', 1),
('B1', 'GFC2', 0),
('B1', 'GFC3', 0),
('B1', 'AFC1', 1),
('B1', 'AFC2', 0),
('B2', 'GFC1', 0),
('B2', 'GFC2', 1),
('B2', 'GFC3', 0),
('B2', 'AFC1', 0),
('B2', 'AFC2', 1),
('B2', 'GFC1', 0),
('B2', 'GFC2', 1),
('B2', 'GFC3', 0),
('B2', 'AFC1', 0),
('B2', 'AFC2', 1)
;
基本上是这样的,
+-------------+-------------+------------+
| ID_Question | ID_Solution | ID_Mapping |
+-------------+-------------+------------+
| B1 | GFC1 | 1 |
| B1 | GFC2 | 0 |
| B1 | GFC3 | 0 |
| B1 | AFC1 | 1 |
| B1 | AFC2 | 0 |
| B2 | GFC1 | 0 |
| B2 | GFC2 | 1 |
| B2 | GFC3 | 0 |
| B2 | AFC1 | 0 |
| B2 | AFC2 | 1 |
| B2 | GFC1 | 0 |
| B2 | GFC2 | 1 |
| B2 | GFC3 | 0 |
| B2 | AFC1 | 0 |
| B2 | AFC2 | 1 |
+-------------+-------------+------------+
我想知道我是否可以将动态(可以添加和删除数据的地方)显示为:
+-----------+------+------+------+------+------+
| ID_SOLUSI | GFC1 | GFC2 | GFC3 | ASF1 | AFC2 |
+-----------+------+------+------+------+------+
| B1 | 1 | 0 | 0 | 1 | 1 |
+-----------+------+------+------+------+------+
| B2 | 0 | 1 | 0 | 1 | 0 |
+-----------+------+------+------+------+------+
| B3 | 1 | 0 | 0 | 0 | 1 |
+-----------+------+------+------+------+------+
我试过使用它,但它似乎不起作用:
SET @sql_ = (
SELECT
GROUP_CONCAT(DISTINCT(CONCAT("ID_mapping AS " , ID_Solution))
FROM table1
);
SET @SQL = CONCAT('SELECT ID_QUESTION, ',
@sql_dinamis , '
FROM tabl1
GROUP BY ID_QUESTION
WITH ROLLUP'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
如果你也能向我解释这个概念就太好了,因为我有点不擅长 SQL 查询(太棒了)
您在此处尝试使用的动态 SQL 背后的想法是,使用一个查询生成另一个查询,然后您可以执行该查询。
首先可视化您尝试动态构建的查询可能会有所帮助。对于您的示例数据,这将是:
select
id_question,
max(case when id_solution = 'AFC1' then id_mapping end) as `AFC1`,
max(case when id_solution = 'AFC2' then id_mapping end) as `AFC2`,
max(case when id_solution = 'GFC1' then id_mapping end) as `GFC1`,
max(case when id_solution = 'GFC2' then id_mapping end) as `GFC2`,
max(case when id_solution = 'GFC3' then id_mapping end) as `GFC3`
from Table1
group by id_question with rollup
这是用于该目的的代码:
-- generate the `max()` expressions in the `from` clause
set @sql = (
select group_concat(
distinct 'max(case when id_solution = ''', id_solution, ''' then id_mapping end) as `', id_solution, '`'
order by id_solution
separator ', '
) from Table1
);
-- debug
select @sql;
-- now build the rest of the query string
set @sql = concat('select id_question, ', @sql, ' from Table1 group by id_question with rollup');
-- debug
select @sql;
-- finally, run the query for good
prepare stmt from @sql;
execute stmt;
deallocate prepare stmt;
嗨,我有一个动态 table 看起来像这样,
CREATE TABLE Table1
(`ID_Question` varchar(2), `ID_Solution` varchar(4), `ID_Mapping` int)
;
INSERT INTO Table1
(`ID_Question`, `ID_Solution`, `ID_Mapping`)
VALUES
('B1', 'GFC1', 1),
('B1', 'GFC2', 0),
('B1', 'GFC3', 0),
('B1', 'AFC1', 1),
('B1', 'AFC2', 0),
('B2', 'GFC1', 0),
('B2', 'GFC2', 1),
('B2', 'GFC3', 0),
('B2', 'AFC1', 0),
('B2', 'AFC2', 1),
('B2', 'GFC1', 0),
('B2', 'GFC2', 1),
('B2', 'GFC3', 0),
('B2', 'AFC1', 0),
('B2', 'AFC2', 1)
;
基本上是这样的,
+-------------+-------------+------------+
| ID_Question | ID_Solution | ID_Mapping |
+-------------+-------------+------------+
| B1 | GFC1 | 1 |
| B1 | GFC2 | 0 |
| B1 | GFC3 | 0 |
| B1 | AFC1 | 1 |
| B1 | AFC2 | 0 |
| B2 | GFC1 | 0 |
| B2 | GFC2 | 1 |
| B2 | GFC3 | 0 |
| B2 | AFC1 | 0 |
| B2 | AFC2 | 1 |
| B2 | GFC1 | 0 |
| B2 | GFC2 | 1 |
| B2 | GFC3 | 0 |
| B2 | AFC1 | 0 |
| B2 | AFC2 | 1 |
+-------------+-------------+------------+
我想知道我是否可以将动态(可以添加和删除数据的地方)显示为:
+-----------+------+------+------+------+------+
| ID_SOLUSI | GFC1 | GFC2 | GFC3 | ASF1 | AFC2 |
+-----------+------+------+------+------+------+
| B1 | 1 | 0 | 0 | 1 | 1 |
+-----------+------+------+------+------+------+
| B2 | 0 | 1 | 0 | 1 | 0 |
+-----------+------+------+------+------+------+
| B3 | 1 | 0 | 0 | 0 | 1 |
+-----------+------+------+------+------+------+
我试过使用它,但它似乎不起作用:
SET @sql_ = (
SELECT
GROUP_CONCAT(DISTINCT(CONCAT("ID_mapping AS " , ID_Solution))
FROM table1
);
SET @SQL = CONCAT('SELECT ID_QUESTION, ',
@sql_dinamis , '
FROM tabl1
GROUP BY ID_QUESTION
WITH ROLLUP'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
如果你也能向我解释这个概念就太好了,因为我有点不擅长 SQL 查询(太棒了)
您在此处尝试使用的动态 SQL 背后的想法是,使用一个查询生成另一个查询,然后您可以执行该查询。
首先可视化您尝试动态构建的查询可能会有所帮助。对于您的示例数据,这将是:
select
id_question,
max(case when id_solution = 'AFC1' then id_mapping end) as `AFC1`,
max(case when id_solution = 'AFC2' then id_mapping end) as `AFC2`,
max(case when id_solution = 'GFC1' then id_mapping end) as `GFC1`,
max(case when id_solution = 'GFC2' then id_mapping end) as `GFC2`,
max(case when id_solution = 'GFC3' then id_mapping end) as `GFC3`
from Table1
group by id_question with rollup
这是用于该目的的代码:
-- generate the `max()` expressions in the `from` clause
set @sql = (
select group_concat(
distinct 'max(case when id_solution = ''', id_solution, ''' then id_mapping end) as `', id_solution, '`'
order by id_solution
separator ', '
) from Table1
);
-- debug
select @sql;
-- now build the rest of the query string
set @sql = concat('select id_question, ', @sql, ' from Table1 group by id_question with rollup');
-- debug
select @sql;
-- finally, run the query for good
prepare stmt from @sql;
execute stmt;
deallocate prepare stmt;