mysql - 在 MySQL 中将数据从行转置到列(没有任何聚合)
问题描述
我需要在 MySQL 中将数据从行转换为列,但没有任何聚合。
例如,我有下表:
CREATE TABLE `MyTable` ( `id` INT NOT NULL AUTO_INCREMENT ,`city` VARCHAR(10) NOT NULL ,
`category` VARCHAR(10) NOT NULL , `item`VARCHAR(10) NOT NULL , `price` DECIMAL(5,2) NOT NULL ,
`date` DATE NOT NULL ,PRIMARY KEY (`id`)) ENGINE = InnoDB;
使用以下数据:
INSERT INTO `MyTable` (`id`, `city`, `category`, `item`, `price`, `date`) VALUES (NULL, 'A', 'Cat1','It1', '10.00', '2018-01-01'),
(NULL, 'A', 'Cat1','It1', '20.00', '2018-01-02'),
(NULL, 'A', 'Cat1','It2', '30.00', '2018-01-03'),
(NULL, 'A', 'Cat2','It1', '40.00', '2018-01-04'),
(NULL, 'B', 'Cat1','It1', '50.00', '2018-01-05'),
(NULL, 'A', 'Cat1', 'It1', '100.00', '2018-02-11'),
(NULL, 'A', 'Cat1','It1', '200.00', '2018-02-12'),
(NULL, 'A', 'Cat1','It2', '300.00', '2018-02-13'),
(NULL, 'A', 'Cat2','It1', '400.00', '2018-02-14'),
(NULL, 'B', 'Cat1','It1', '500.00', '2018-02-15')
当我使用这个查询
SELECT city, category, item, sum(CASE WHEN EXTRACT(YEAR_MONTH FROM `date`) = "201801"
THEN price ELSE 0 END) AS "Jan", sum(CASE WHEN EXTRACT(YEAR_MONTH FROM `date`) = "201802"
THEN price ELSE 0 END) AS "Feb" FROM MyTable WHERE 1 GROUP BY city, category, item
然后我得到'Item1'的汇总结果:
但我需要没有任何聚合的所有事务:
我应该如何编写查询以获得正确的结果?
解决方案
您尝试做的一般类称为PIVOT。在 PIVOT 中,行的子集就像表一样,因为来自单个列的数据被划分为多个列。 JOIN
可以在这里为您提供帮助:
SELECT
tblItems.city, tblItems.category, tblItems.item,
tblJan.price AS Jan,
tblFeb.price AS Feb
FROM
(SELECT city, category, item
FROM MyTable
GROUP BY city, category, item) AS tblItems
INNER JOIN
(SELECT city, category, item, price
FROM MyTable
WHERE EXTRACT(YEAR_MONTH FROM `date`) = "201801") AS tblJan
ON (tblItems.city = tblJan.city AND tblItems.category = tblJan.category AND tblItems.item = tblJan.item)
INNER JOIN
(SELECT city, category, item, price
FROM MyTable
WHERE EXTRACT(YEAR_MONTH FROM `date`) = "201802") AS tblFeb
ON (tblItems.city = tblFeb.city AND tblItems.category = tblFeb.category AND tblItems.item = tblFeb.item)
ORDER BY tblItems.city, tblItems.category, tblItems.item;
SQL 小提琴:http ://sqlfiddle.com/#!9/f77978a/3
但是,您的下一个问题将是:“如果我不提前知道我将拥有多少个子表,我该如何动态地执行此操作?” 在手头的情况下,这可能无关紧要,因为一年中有固定的月份数。但迟早你会想要动态地执行 PIVOT。
一些 RDBMS 具有内置PIVOT
功能,但不幸的是,MySQL 不是其中之一。因此,对于 MySQL,您需要动态构建 PIVOT 查询的逻辑,然后执行构建的查询。该逻辑可以在 MySQL 中的存储过程中,也可以在具有 MySQL 库函数的外部语言中(大多数现代语言都有)。
编辑:或者,您可以考虑遵循@Madhur Bhaiya 的评论,并将信息的显示委托给从数据库中获取数据的程序;SQL 很强大,但是——与其他一切一样——它不是满足您所有需求的正确位置。
推荐阅读
- python - 使用 parsimonious 解析潜在函数的参数
- typescript - 将分布式条件类型与泛型方法结合使用时的问题
- python - 如何在 Python 中准确解释大浮点数
- python - 无法发布具有外部依赖项的 azure python 函数应用程序(不在索引中)
- javascript - DataTables 从数据库中呈现错误的 DateTime 值
- python - 将 forloop 转换为列表理解
- php - 查询在行中返回 0
- python - 如何避免注销功能删除有关会话的信息
- python - 用于大型 Unicode 文本的 Python 查找器或子程序
- javascript - 如何制作带声音的背景视频播放列表工作