You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调整SQL查询将店铺每日订单数据转为日期列横向展示?

实现店铺每日订单数的行转列展示

首先修正你原SQL中的笔误:WHERE子句里的order_created应该是created_at,否则会因字段不存在或逻辑错误导致结果异常。

要将纵向的(日期+店铺)分组结果转为店铺为行、日期为列的横向格式,主要有两种实现方式,取决于你的日期范围是否固定:

一、日期范围固定(如你指定的2023年10月):使用条件聚合

这是通用所有SQL数据库的写法,通过CASE WHEN配合聚合函数(COUNT)来生成每个日期的列:

SELECT 
  shop_id AS 店铺ID,
  COUNT(CASE WHEN DATE(created_at) = '2023-10-01' THEN 1 END) AS '2023-10-01',
  COUNT(CASE WHEN DATE(created_at) = '2023-10-02' THEN 1 END) AS '2023-10-02',
  -- 依次添加10月剩余日期的CASE语句
  COUNT(CASE WHEN DATE(created_at) = '2023-10-31' THEN 1 END) AS '2023-10-31'
FROM orders
WHERE 
  created_at >= '2023-10-01' 
  AND created_at < '2023-11-01'
  AND shop_id IN (123, 567)
GROUP BY shop_id;

说明:

  • CASE WHEN会判断当前行的日期是否匹配指定日期,匹配则返回1,否则返回NULL;COUNT会忽略NULL值,从而统计出该店铺当日的订单数。
  • 如果需要显示为01/10/2023这种格式的列名,只需修改AS后的别名,比如AS '01/10/2023'。

二、日期范围不固定:使用动态SQL或数据库专属PIVOT功能

如果日期范围经常变化,手动写CASE WHEN会很繁琐,这时可以用数据库专属的行转列功能:

1. MySQL/MariaDB:动态生成条件聚合语句

通过预处理语句动态拼接日期列:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'COUNT(CASE WHEN DATE(created_at) = ''',
      DATE(created_at),
      ''' THEN 1 END) AS ''',
      DATE(created_at),
      ''''
    )
  ) INTO @sql
FROM orders
WHERE 
  created_at >= '2023-10-01' 
  AND created_at < '2023-11-01'
  AND shop_id IN (123, 567);

SET @sql = CONCAT('SELECT shop_id AS 店铺ID, ', @sql, ' FROM orders WHERE created_at >= ''2023-10-01'' AND created_at < ''2023-11-01'' AND shop_id IN (123, 567) GROUP BY shop_id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

2. SQL Server:使用PIVOT关键字

SELECT 
  shop_id AS 店铺ID,
  [2023-10-01], [2023-10-02], ..., [2023-10-31]
FROM (
  SELECT 
    shop_id,
    DATE(created_at) AS order_date,
    1 AS order_flag
  FROM orders
  WHERE 
    created_at >= '2023-10-01' 
    AND created_at < '2023-11-01'
    AND shop_id IN (123, 567)
) AS src
PIVOT (
  COUNT(order_flag)
  FOR order_date IN ([2023-10-01], [2023-10-02], ..., [2023-10-31])
) AS pvt;

如果要动态生成PIVOT的列,同样需要用动态SQL拼接IN子句中的日期列表。

3. PostgreSQL:使用crosstab扩展

需要先安装tablefunc扩展,然后执行:

-- 先启用扩展(仅需执行一次)
CREATE EXTENSION IF NOT EXISTS tablefunc;

SELECT * FROM crosstab(
  'SELECT shop_id, DATE(created_at), COUNT(*) 
   FROM orders 
   WHERE created_at >= ''2023-10-01'' AND created_at < ''2023-11-01'' AND shop_id IN (123, 567)
   GROUP BY shop_id, DATE(created_at)
   ORDER BY shop_id, DATE(created_at)',
  'SELECT DISTINCT DATE(created_at) FROM orders WHERE created_at >= ''2023-10-01'' AND created_at < ''2023-11-01'' ORDER BY DATE(created_at)'
) AS ct(
  店铺ID INT,
  "2023-10-01" INT,
  "2023-10-02" INT,
  -- 依次添加剩余日期的列定义
  "2023-10-31" INT
);

内容的提问来源于stack exchange,提问作者Josh Bolton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 19:20:15