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

SQL行转列实现:将时间区间按类别分列展示的查询需求

实现SQL方案

核心思路

  1. 用窗口函数ROW_NUMBER()分别给class1、class2的时间区间按时间升序生成序号,序号相同的就是需要放在同一行的同序位区间
  2. 以生成的序号为关联条件,关联两类的区间数据,无匹配时自动补NULL
  3. 按序号排序保证结果顺序符合预期

完整SQL语句

假设你的表名为time_class,如果是其他表名自行替换即可:

WITH class1_rn AS (
    SELECT 
        `interval` AS class1,
        ROW_NUMBER() OVER (ORDER BY `interval` ASC) AS rn
    FROM time_class
    WHERE class = 'class1'
),
class2_rn AS (
    SELECT 
        `interval` AS class2,
        ROW_NUMBER() OVER (ORDER BY `interval` ASC) AS rn
    FROM time_class
    WHERE class = 'class2'
)
SELECT 
    c1.class1,
    c2.class2
FROM class1_rn c1
FULL OUTER JOIN class2_rn c2 
    ON c1.rn = c2.rn
ORDER BY COALESCE(c1.rn, c2.rn) ASC;

注:interval是SQL保留关键字,所以用反引号包裹做转义,PostgreSQL、SQL Server等数据库可替换为双引号转义。MySQL不支持FULL OUTER JOIN,如果使用MySQL可直接替换为LEFT JOIN,适配你的样例场景下class1数量更多的情况。如果你的数据库不支持CTE语法(比如低于8.0版本的MySQL),可以把CTE部分改成子查询写法。

低版本MySQL适配方案

如果使用的MySQL版本低于8.0,不支持窗口函数,可以用变量手动生成序号:

SELECT 
    c1.class1,
    c2.class2
FROM (
    SELECT 
        `interval` AS class1,
        @rn1 := @rn1 + 1 AS rn
    FROM time_class, (SELECT @rn1 := 0) init
    WHERE class = 'class1'
    ORDER BY `interval` ASC
) c1
LEFT JOIN (
    SELECT 
        `interval` AS class2,
        @rn2 := @rn2 + 1 AS rn
    FROM time_class, (SELECT @rn2 := 0) init
    WHERE class = 'class2'
    ORDER BY `interval` ASC
) c2 ON c1.rn = c2.rn
ORDER BY c1.rn ASC;

内容的提问来源于stack exchange,提问作者Cornel Militaru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 18:18:05