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

基于CTE统计各ID工作日与非工作日天数的技术咨询

问题解答

你的实现思路没问题,但有个小语法错误,而且可以更高效。

你的实现修正与可行性

你把宽表转成单行长表再统计的逻辑是成立的,但代码里第一个GROUP BY shop_id应该改成GROUP BY id(原CTE里根本没shop_id字段),修正后就能正常跑。不过手动写VALUES把宽表拆成长表的方式太死板——数据变多或者星期列调整时,手动改很容易错,也麻烦。

更优的实现方式(直接基于原CTE处理)

不用手动拆表,直接通过列转行的方式处理原宽表,灵活又好维护:

方式1:用UNNEST(PostgreSQL等支持数组的数据库)

WITH a(id, MON, TUE, WED, THUR, FRI, SAT, SUN) AS (
    VALUES (1,0,0,1,1,1,0,0),(2,1,1,1,1,0,0,0)
)
SELECT 
    id,
    CASE 
        WHEN day_name IN ('MON','TUE','WED','THUR','FRI') THEN 'Working'
        ELSE 'Non-working'
    END AS day_type,
    SUM(day_value) AS "COUNT"
FROM a
CROSS JOIN UNNEST(
    ARRAY['MON','TUE','WED','THUR','FRI','SAT','SUN'],
    ARRAY[MON,TUE,WED,THUR,FRI,SAT,SUN]
) AS days(day_name, day_value)
GROUP BY id, day_type
ORDER BY id, day_type;

方式2:通用SQL(兼容所有主流数据库)

如果你的数据库不支持UNNEST,用UNION ALL拆列就行:

WITH a(id, MON, TUE, WED, THUR, FRI, SAT, SUN) AS (
    VALUES (1,0,0,1,1,1,0,0),(2,1,1,1,1,0,0,0)
)
-- 统计工作日
SELECT 
    id,
    'Working' AS day_type,
    SUM(day_value) AS "COUNT"
FROM (
    SELECT id, MON AS day_value FROM a
    UNION ALL SELECT id, TUE FROM a
    UNION ALL SELECT id, WED FROM a
    UNION ALL SELECT id, THUR FROM a
    UNION ALL SELECT id, FRI FROM a
) working_days
GROUP BY id
UNION ALL
-- 统计非工作日
SELECT 
    id,
    'Non-working' AS day_type,
    SUM(day_value) AS "COUNT"
FROM (
    SELECT id, SAT AS day_value FROM a
    UNION ALL SELECT id, SUN FROM a
) non_working_days
GROUP BY id
ORDER BY id, day_type;

两种方案对比

  • 你的修正后实现:逻辑简单,但扩展性差,只适合小数据量临时用。
  • 推荐方案:自动列转行,不用手动维护数据,修改或扩展星期列时只需调整对应部分,更适合长期使用。

内容的提问来源于stack exchange,提问作者Ms.kitty

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:35:34