car*_*gie 3 sql-server case group-by
我有以下查询,从星期一开始,按周返回一组计数,一行是汇总总数。
select distinct
DATEPART(ISO_WEEK, ig.IN_EVT_DT_TM) as B2B_Week,
count (distinct bm.MISSION_ID) as B2B_Mission,
count (distinct dl.DRIVER) as Distinct_B2B_Drivers
from
DD.B2B_MISSIONS bm
inner join dd.IN_GATE ig on bm.MISSION_ID = ig.IN_MISSION_ID
inner join dd.XNS_DRIVER_LOGIN dl on ig.IN_DRIVER_ID = dl.driver
group by
DATEPART(ISO_WEEK, ig.IN_EVT_DT_TM)
with rollup
order by
DATEPART(ISO_WEEK, ig.IN_EVT_DT_TM)
;
Run Code Online (Sandbox Code Playgroud)
我的结果表如下所示:
B2B_Week B2B_Mission Distinct_B2B_Drivers
1647 357
44 717 264
45 930 301
Run Code Online (Sandbox Code Playgroud)
我希望它看起来像这样:
B2B_Week B2B_Mission Distinct_B2B_Drivers
44 717 264
45 930 301
TOTAL 1647 357
Run Code Online (Sandbox Code Playgroud)
问题
总计行出现在顶部而不是底部。这很可能与第二个问题有关。
我一直无法使用 CASE 语句返回日期列为 NULL 的“TOTAL”。主要问题是 DATE 是 INT 而 'TOTAL' 不是。我已经尝试了在整个 CASE 语句或只是它的一部分上使用 CAST 的各种方法。我试过将 Case 语句放在 SELECT 或 GROUP BY 语句中。
这是当我尝试让 TOTAL 出现时会发生什么的示例。
case when DATEPART(ISO_WEEK, ig.IN_EVT_DT_TM) is null
then 'TOTAL' else DATEPART(ISO_WEEK, ig.IN_EVT_DT_TM) end
Run Code Online (Sandbox Code Playgroud)
“将 varchar 值 'TOTAL' 转换为数据类型 int 时,转换失败。”
我究竟做错了什么?
您应该使用该GROUPING功能
GROUPING 在结果集中返回 1 表示聚合或 0 表示未聚合。
这样做的好处是它会正确处理B2B_Week本身的情况,NULL不会错误地将其视为总行。
WITH T
AS (SELECT DATEPART(ISO_WEEK, ig.IN_EVT_DT_TM) AS B2B_Week,
bm.MISSION_ID,
dl.DRIVER
FROM DD.B2B_MISSIONS bm
INNER JOIN dd.IN_GATE ig
ON bm.MISSION_ID = ig.IN_MISSION_ID
INNER JOIN dd.XNS_DRIVER_LOGIN dl
ON ig.IN_DRIVER_ID = dl.driver)
SELECT B2B_Week = CASE WHEN GROUPING(B2B_Week) = 0 THEN CAST(B2B_Week AS VARCHAR(5)) ELSE 'Total' END,
B2B_Mission = COUNT (DISTINCT MISSION_ID),
Distinct_B2B_Drivers = COUNT (DISTINCT DRIVER)
FROM T
GROUP BY B2B_Week WITH ROLLUP
ORDER BY GROUPING(B2B_Week),
T.B2B_Week
Run Code Online (Sandbox Code Playgroud)