有关mySQL的问题。 我正在从看起来像这样的.csv文件中读取数据
原始表
------------------------------------
Id 2018M01 2018M02 2018M03
------------------------------------
EMEA 3 1 4
ASPAC 4 5 4
ASPAC 1 2 1
预期结果
---------------------
ID Month Qty
---------------------
EMEA 2018M01 3
EMEA 2018M02 1
EMEA 2018M03 4
ASPAC 2018M01 4
.......
months列标题是动态的,即每个月都会有新的月份而旧的月份将被删除。但是,列总数将保持不变。
因此,只要月份列标题发生更改,我都希望SQL代码能够动态读取并提供正确的结果,而无需我手动更改部分代码。
我写了以下代码;代码是取消透视月份列。但是,我通过将2018M03更改为2018M04并重新运行SQL代码来手动对.csv文件头进行更改来测试代码,但是它似乎仍然可以打印旧数据。我在做什么错了?
谢谢。我对SQL相当陌生。
DROP TABLE IF EXISTS book;
CREATE TABLE book (
ID VARCHARACTER(10),
2018M01 decimal(4,2),
2018M02 decimal(4,2),
2018M03 decimal(4,2)
);
LOAD DATA LOCAL INFILE '/Users/blytonpereira/Desktop/Book1.csv' REPLACE INTO TABLE book
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 LINES;
DESCRIBE book;
SELECT ID, '2018M01' AS month, 2018M01 AS qty from book
UNION ALL
SELECT ID, '2018M02' AS month, 2018M02 AS qty from book
UNION ALL
SELECT ID, '2018M03' AS month, 2018M03 AS qty from book;
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'select ID, ''',
c.column_name,
''' AS month, ',
c.column_name,
' as qty
from book
where ',
c.column_name,
' > 0'
) SEPARATOR ' UNION ALL '
) INTO @sql
FROM information_schema.columns c
where c.table_name = 'book'
and c.column_name not in ('id')
order by c.ordinal_position;
SET @sql
= CONCAT('select id, month, qty
from
(', @sql, ') x order by id');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
);
答案 0 :(得分:2)
**更新后的答案: 该解决方案是动态的,无论表中的列如何,它都会填充它们并以所需格式提取信息。为确保各列之间必须有共同点,例如它们都以“ 2018”开头,您可以根据需要在Query中进行更改。
SELECT
GROUP_CONCAT(
CONCAT(
'SELECT id, ''', COLUMN_NAME, ''' as month, ', COLUMN_NAME, ' as QTY FROM t1 ') SEPARATOR ' UNION ALL ')
FROM
`INFORMATION_SCHEMA`.`COLUMNS`
WHERE
`COLUMN_NAME` LIKE '2018%'
INTO @sql;
SET @query = CONCAT('select id, month, QTY from (' , @sql , ') x order by id;');
SELECT @query;
PREPARE stmt FROM @query;
EXECUTE stmt;
**注意:查询有2个输出,第一个是准备好的串联查询字符串(只是想知道运行前的样子),另一个是实际数据。如果只需要实际数据,则可以注释(SELECT @query;)或将其删除。