如何根据日期列将行转换为列?

Posted

技术标签:

【中文标题】如何根据日期列将行转换为列?【英文标题】:how to convert rows to columns based on date column? 【发布时间】:2015-09-07 11:31:10 【问题描述】:

这里是 SQL 小提琴

http://sqlfiddle.com/#!9/25542/2/0

我只想获取我的数据

Sale_On    | Count Refunded | Count Sale | Count Cashback
-------------------------------------------------------
2015-09-07 |   1            |    5       |     1

我阅读了 mysql 中的“case-when”,但在这种情况下,我必须手动编写每个 order_status。

我该怎么做?除了将行转换为列之外,还有其他解决方案吗?

【问题讨论】:

ordersorder_detail 之间出现RIGHT JOIN 很奇怪:如果order_idorders 中不存在,但在order_detail 中存在,那么肯定应该在这个查询——即你想要一个 inner 连接(如果你想包含存在于orders 但不包含order_detailorder_ids,那么左连接也可能是合适的,尽管没有@ 987654333@ 在这种情况下,不会有任何区别)。 是的,应该是内连接。我错误地写了正确的加入。 A more generic answer 到“枢轴”问题。 【参考方案1】:

如果您愿意对状态进行硬编码,则可以对它们执行聚合:

SELECT   DATE(o.sale_on),
         SUM(od.order_status=1) AS Sales,
         SUM(od.order_status=2) AS Refunds,
         SUM(od.order_status=3) AS Cashbacks
FROM     orders o RIGHT JOIN order_detail od USING (order_id)
GROUP BY DATE(o.sale_on)

在sqlfiddle 上查看。

否则,您实际上需要使用对master_order_status 表的查询来动态生成类似的 SQL,以在选择列表中生成相应的列。

【讨论】:

你能解释一下这里sum的用处吗?为什么我不能在这里使用 count ? @SunilGarg: COUNT(expr) "返回由@987654329 检索的行中expr 的非NULL 值的计数@声明”。由于布尔表达式 od.order_status=1 等总是计算为 1 或 0,因此它们总是非 NULL。您想将这些 1 相加,即SUM() 我们不能动态地做吗?与其手动提及每个状态,不如从 master_order_status 自动获取。 @SunilGarg:这不是我回答的最后一段所说的吗?【参考方案2】:

或者试试这个

select sale_on,
max(case when status='sale' then c end) as count_Sales,
max(case when status='Refunded' then c end) as count_Refunded,
max(case when status='CashBack' then c end) as count_CashBack
from
(
SELECT o.sale_on,od.order_status,COUNT(*) as c,mos.status FROM orders o
RIGHT JOIN order_detail od ON o.order_id = od.order_id
LEFT JOIN `master_order_status` mos ON mos.`status_id` = od.order_status
GROUP BY DATE(o.sale_on),od.order_status
  ) as t group by sale_on

SQL 小提琴http://sqlfiddle.com/#!9/25542/13

【讨论】:

以上是关于如何根据日期列将行转换为列?的主要内容,如果未能解决你的问题,请参考以下文章

根据排名将行转换为列

将行转换为涉及日期的列

SQL Server - Pivot 将行转换为列(带有额外的行数据)

根据条件将行转换为列

Mysql查询根据两列动态将行转换为列

使用 PIVOT 将行转换为列