iT邦幫忙

0

SQL 取第一筆加總問題

sum

想請教大家
我想要將資料表的 LoginTime 進行加總
但 BeginTimePeriodDt 在同一區間 (2018-10-02 09:30:00.000 ) 可能會有多筆資料 Service_Id 不同
請問是否可以只取同一時間區間的第一筆進行加總

https://ithelp.ithome.com.tw/upload/images/20181005/20112266ZCbNfRnSqU.jpg

感謝!!

看更多先前的討論...收起先前的討論...
浩瀚星空 iT邦研究生 3 級 ‧ 2018-10-05 16:39:56 檢舉
SELECT sum(???) FROM
(
SELECT * FROM db GROUP BY BeginTimePeriodDt
) AS g
暐翰 iT邦大師 5 級 ‧ 2018-10-05 16:58:22 檢舉
資料庫是什麼呢? sql-server?
暐翰 iT邦大師 5 級 ‧ 2018-10-05 17:05:18 檢舉
> 只取同一時間區間的第一筆

怎麼判斷抓哪個第一筆,數量最大的?
pcw iT邦研究生 4 級 ‧ 2018-10-05 17:11:50 檢舉
我也不知道他要Sum甚麼。
kenkotw iT邦新手 5 級 ‧ 2018-10-05 17:24:49 檢舉
暐翰您好
可以取 Service_id 最大的那筆
kenkotw iT邦新手 5 級 ‧ 2018-10-05 17:27:19 檢舉
我主要是要將 totallogintime & totalidletime 進行加總
但同一時間區段 2018-10-02 09:30:00.000 會有二筆 Service_ID
不過這二筆在 totallogintime & totalidletime 的值是相同的
是否可只取其中一筆進行加總

感謝解惑
暐翰 iT邦大師 5 級 ‧ 2018-10-05 17:38:12 檢舉
可以 我在下面解答了
你看是不是你想要的

2 個回答

0
暐翰
iT邦大師 5 級 ‧ 2018-10-05 17:10:43

您好
我目前是使用 SQL 2012 R2 版本
DB 名稱是 AgentActivitySummary
欄位如下
BeginTimePeriodDt User_Id Service_Id LoginDt WorkGroup_Id EndTimePeriodDt Site_Id TenantId TotalLoginTime TotalIdleTime

DB 欄位長相如下圖
https://ithelp.ithome.com.tw/upload/images/20181006/20112266Z70N9y9ZsC.jpg

我目前使用的語法如下
select a.user_id
, sum(case when (a.service_id ='0') then a.TotalLoginTime else null end) as TotalLoginTime
, sum(case when (a.service_id ='0') then a.TotalIdleTime else null end) as TotalidleTime
, sum(case whenservice_id not in ('0') and a.service_id not in ('53000462')) then a.TotalLoginTime else null end) as ServiceLoginTime
, sum( case when (a.service_id not in ('0') and a.service_id not in ('53000462')) then a.TotalIdleTime else null end) as ServiceidleTime
--sum (TotalLoginTime) as total_login

from AgentActivitySummary a
where (a.BeginTimePeriodDt>='2018-10-03' and a.BeginTimePeriodDt <='2018-10-04')
--and a.user_id ='RY16013' --and (service_id not in ('0', '53000462'))
group by a.user_id

在第三欄和第四欄查詢的結果
需排除 service_id ('0') and ('53000462')
但其他 service_ID (53000485, 53000577) 我只要取其中一筆就好
希望查詢出來的的結果如下圖

https://ithelp.ithome.com.tw/upload/images/20181006/201122666tPF8TAlHr.jpg

謝謝大家的幫忙

使用以下Script:
CTE概念,可以把它當成變數保存查詢就可以
假如還不清楚可以看T-SQL查询进阶--详解公用表表达式(CTE) - CareySon - 博客园

with CTE as (
	select * from AgentActivitySummary
	where [Service_Id] not in ('53000485','53000577') /*先排除53000485, 53000577,後面篩選玩第一筆資料,使用union all把資料加回來*/
)
,CTE2 as (
	select BeginTimePeriodDt,User_id,Service_Id,LoginDt,WorkGroup_Id,EndTimePeriodDt,Site_Id,TenantId,TotalLoginTime,TotalIdleTime from (
		select row_number() over (
			partition by [BeginTimePeriodDt], [User_Id] --BeginlimePeriodDt同一時間區間分組
			order by [Service_Id] desc /*Service倒序,以便後面取最大第一筆*/
		) rnk,* from AgentActivitySummary
		where [Service_Id] in ('53000485','53000577')  /*service_ID (53000485, 53000577) 我只要取其中一筆就好 , (可以取 Service_id 最大的那筆)*/
	) T
	where rnk = 1
),CTE3 as (
	select * from CTE
	union all
	select * from CTE2
)
select a.user_id
	, sum(case when (a.service_id ='0') then a.TotalLoginTime else null end) as TotalLoginTime
	, sum(case when (a.service_id ='0') then a.TotalIdleTime else null end) as TotalidleTime
	, sum(case when (service_id not in ('0','53000462')) then a.TotalLoginTime else null end) as ServiceLoginTime
	, sum(case when (a.service_id not in ('0','53000462')) then a.TotalIdleTime else null end) as ServiceidleTime
from CTE3 a
where (a.BeginTimePeriodDt>='2018-10-02' and a.BeginTimePeriodDt <='2018-10-04')
group by a.user_id


測試資料

CREATE TABLE AgentActivitySummary
	([BeginTimePeriodDt] datetime, [User_id] varchar(7), [Service_Id] int, [LoginDt] datetime, [WorkGroup_Id] int, [EndTimePeriodDt] varchar(23)
	, [Site_Id] int, [TenantId] int, [TotalLoginTime] int, [TotalIdleTime] int)
;
	
INSERT INTO AgentActivitySummary
	([BeginTimePeriodDt], [User_id], [Service_Id], [LoginDt], [WorkGroup_Id], [EndTimePeriodDt], [Site_Id], [TenantId], [TotalLoginTime], [TotalIdleTime])
VALUES
	('2018-10-02 09:30:00', 's110047', 0, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 720, 0),
	('2018-10-02 09:30:00', 's110047', 53000462, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 720, 0),
	('2018-10-02 09:30:00', 's110047', 53000485, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 720, 0),
	('2018-10-02 09:30:00', 's110047', 53000577, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 720, 0),
	('2018-10-02 09:45:00', 's110047', 0, '2018-10-02 09:32:59', 53000132, '2018-10-0210:00:00.000', 54, 1, 900, 0),
	('2018-10-02 09:45:00', 's110047', 53000462, '2018-10-02 09:32:59', 53000132, '2018-10-02 10:00:00.000', 54, NULL, 900, 0),
	('2018-10-02 09:45:00', 's110047', 53000485, '2018-10-02 09:32:59', 53000132, '2018-10-02 10:00:00.000', 54, NULL, 900, 0),
	('2018-10-02 09:45:00', 's110047', 53000577, '2018-10-02 09:32:59', 53000132, '2018-10-0210:00:00.000', 54, NULL, 900, 0),
	('2018-10-02 10:00:00', 's110047', 0, '2018-10-02 09:32:59', 53000132, '2018-10-02 10:15:00.000', 54, NULL, 900, 0),
	('2018-10-02 10:00:00', 's110047', 53000462, '2018-10-02 09:32:59', 53000132, '2018-10-0210:15:00.000', 54, NULL, 900, 0),
	('2018-10-02 10:00:00', 's110047', 53000485, '2018-10-02 09:32:59', 53000132, '2018-10-0210:15:00.000', 54, 1, 900, 0),
	('2018-10-02 10:00:00', 's110047', 53000577, '2018-10-02 09:32:59', 53000132, '2018-10-0210:15:00.000', 54, 1, 900, 0)
;

線上測試連結:SQL Fiddle

看更多先前的回應...收起先前的回應...
kenkotw iT邦新手 5 級 ‧ 2018-10-05 18:16:06 檢舉

想要請教 CTE & CTE2 是我的 table 嗎 ??
LoginTime 並沒在我的欄位內

感謝解式

暐翰 iT邦大師 5 級 ‧ 2018-10-05 18:21:26 檢舉

想要請教 CTE & CTE2 是我的 table 嗎 ??

不是,你把它當成變數保存查詢就可以
查詢也可以改成子查詢

select sum(totallogintime+TotalldleTime) /*進行totallogintime & totalidletime加總*/ 
    as totalSum 
from (
	select * from (
		select row_number() over (
			partition by BeginlimePeriodDt --BeginlimePeriodDt同一時間區間分組
			order by Service desc /*Service倒序,以便後面取最大第一筆*/
		) rnk,* 
		from TestTable	
	)T1 where rnk = 1 /*取Service最大第一筆*/
) T2

LoginTime 並沒在我的欄位內

我把LoginTime改成TestTable表格了


測試連結 : SQL Fiddle

kenkotw iT邦新手 5 級 ‧ 2018-10-05 18:28:58 檢舉

Sorry,我是 SQL 門外漢

我用了列語法
select sum(totallogintime) /進行totallogintime & totalidletime加總/
as totalSum
from (
select * from (
select row_number() over (
partition by BeginlimePeriodDt --BeginlimePeriodDt同一時間區間分組
order by Service_id desc /Service倒序,以便後面取最大第一筆/
) rnk,*
from AgentActivitySummary
)T1 where rnk = 1 /取Service最大第一筆/
) T2

出現錯誤訊息
Msg 207, Level 16, State 1, Line 6
Invalid column name 'BeginlimePeriodDt'.

暐翰 iT邦大師 5 級 ‧ 2018-10-05 19:57:13 檢舉

它的訊息說 欄位名稱錯誤
可以貼你正確表格結構上來嗎?
還有說明你是哪個資料庫,哪個版本

這樣可以幫助解題

張小馬 iT邦新手 5 級 ‧ 2018-10-06 09:30:57 檢舉

大小寫問題吧 加個雙引號改成 partition by "BeginlimePeriodDt"試試

kenkotw iT邦新手 5 級 ‧ 2018-10-06 12:30:20 檢舉

您好
我目前是使用 SQL 2012 R2 版本
DB 名稱是 AgentActivitySummary
欄位如下
BeginTimePeriodDt User_Id Service_Id LoginDt WorkGroup_Id EndTimePeriodDt Site_Id TenantId TotalLoginTime TotalIdleTime

DB 欄位長相如下圖
https://ithelp.ithome.com.tw/upload/images/20181006/20112266Z70N9y9ZsC.jpg

我目前使用的語法如下
select a.user_id
, sum(case when (a.service_id ='0') then a.TotalLoginTime else null end) as TotalLoginTime
, sum(case when (a.service_id ='0') then a.TotalIdleTime else null end) as TotalidleTime
, sum(case whenservice_id not in ('0') and a.service_id not in ('53000462')) then a.TotalLoginTime else null end) as ServiceLoginTime
, sum( case when (a.service_id not in ('0') and a.service_id not in ('53000462')) then a.TotalIdleTime else null end) as ServiceidleTime
--sum (TotalLoginTime) as total_login

from AgentActivitySummary a
where (a.BeginTimePeriodDt>='2018-10-03' and a.BeginTimePeriodDt <='2018-10-04')
--and a.user_id ='RY16013' --and (service_id not in ('0', '53000462'))
group by a.user_id

在第三欄和第四欄查詢的結果
需排除 service_id ('0') and ('53000462')
但其他 service_ID (53000485, 53000577) 我只要取其中一筆就好
希望查詢出來的的結果如下圖

https://ithelp.ithome.com.tw/upload/images/20181006/201122666tPF8TAlHr.jpg

謝謝大家的幫忙

暐翰 iT邦大師 5 級 ‧ 2018-10-06 14:51:23 檢舉

我更新留言回答你新的問題了

rogeryao iT邦研究生 5 級 ‧ 2018-10-06 18:51:13 檢舉

to 暐翰
在每個時段補入
('2018-10-02 09:30:00', 'sl10048','53000485', 720, 200),
sl10048 不會出現,
partition by [BeginTimePeriodDt]
似乎要改成 partition by [BeginTimePeriodDt], [User_Id]

暐翰 iT邦大師 5 級 ‧ 2018-10-06 19:16:35 檢舉

感謝,你說的對
我修正了

rogeryao iT邦研究生 5 級 ‧ 2018-10-06 21:05:41 檢舉

to 暐翰:
你的 SQL
http://sqlfiddle.com/#!18/722c0/1
我的 SQL
http://sqlfiddle.com/#!18/6772c/1

由 View Execution Plan 結果 , 你的 SQL 成本似乎比較低
讚喔

rogeryao iT邦研究生 5 級 ‧ 2018-10-06 22:57:17 檢舉

to 暐翰:
請問幾個問題:
1.我用 max ; 你用 row_number() over (partition by ..order by ..desc <= 取得第一筆前要先做排序
2.我直接 sum ; 你用 sum(case when ....<= sum 之前都要判斷
3.我用 full outer join +兩次 group by , 你用 union + 一次 group by <= 造成我的 SQL 成本較高的原因 ?
4.若此table 有 1 萬筆或是 10 萬筆資料時,跑出來的成本(或時間)會是如何 ? 你有辦法模擬測試嗎 ? 謝謝.

rogeryao iT邦研究生 5 級 ‧ 2018-10-07 13:13:57 檢舉

to 暐翰:
為了便於測試調整兩段你的 SQL
1.where [Service_Id] not in ('53000485','53000577')
=>where [Service_Id] in ('0','53000462')
2.where [Service_Id] in ('53000485','53000577')
=>where [Service_Id] not in ('0','53000462')
3.測試天數 10000 ,每天 10 人 ,每人連線 Service_Id = 40,總資料 400 萬筆,不考慮 BeginTimePeriodDt 篩選變數
4.我的 SQL 約 1 秒 ,你的 SQL 約 13 秒 [ row_number() over (partition by ..order by ..desc <= 成本 71% ]
以上測試條件無任何依據 , 僅任意測試 , 釐清我的想法是否有誤 ,與你分享
謝謝

暐翰 iT邦大師 5 級 ‧ 2018-10-07 14:18:41 檢舉

rogeryao sorry IT邦怪怪的,你留言我都看不到訊息通知

1.我用 max ; 你用 row_number() over (partition by ..order by ..desc <= 取得第一筆前要先做排序

建議使用row_number
因為它可以省掉一次groupby + max動作

2.我直接 sum ; 你用 sum(case when ....<= sum 之前都要判斷

比起在子查詢篩選再多查一次,放在windows function的boolean的判斷是很快的

3.我用 full outer join +兩次 group by , 你用 union + 一次 group by <= 造成我的 SQL 成本較高的原因 ?

是的,這題可以用邏輯先把需要篩選的資料拿出來(減少資料量)
還可以避免再一次子查詢跟group

4.若此table 有 1 萬筆或是 10 萬筆資料時,跑出來的成本(或時間)會是如何 ? 你有辦法模擬測試嗎 ? 謝謝.

可以,insert用t-sql loop跑一千次就可以。

rogeryao iT邦研究生 5 級 ‧ 2018-10-08 21:05:04 檢舉

to 暐翰
需求又變了 , 你有高招嗎 ?

1
rogeryao
iT邦研究生 5 級 ‧ 2018-10-06 12:08:19

1.LoginTime 進行加總
2.原需求 :只取同一時間區間的第一筆進行加總
3.新需求 :但同一時間區段 2018-10-02 09:30:00.000 會有二筆 Service_ID,可以取 Service_id 最大的那筆 <== 已經與第一筆條件無關
借用 暐翰的 Code
CREATE TABLE LoginTime
([BeginTimePeriodDt] datetime, [Service_Id] int, [TotalLoginTime] int, [TotalIdleTime] int)
;

INSERT INTO LoginTime
([BeginTimePeriodDt], [Service_Id], [TotalLoginTime], [TotalIdleTime])
VALUES
('2018-10-02 09:30:00', 53000485, 720, 200),
('2018-10-02 09:30:00', 53000577, 720, 200),
('2018-10-02 09:45:00', 53000485, 900, 300),
('2018-10-02 09:45:00', 53000577, 900, 400),
('2018-10-02 10:00:00', 53000485, 900, 0),
('2018-10-02 10:00:00', 53000577, 900, 0),
('2018-10-02 10:15:00', 53000485, 900, 0),
('2018-10-02 10:15:00', 53000577, 900, 0)
;

select sum(TotalLoginTime) as TotalLoginTime
from LoginTime as B
inner join (
select A.BeginTimePeriodDt,
max(A.Service_Id) as Service_Id
from LoginTime as A
where 1=1
group by A.BeginTimePeriodDt ) as C on C.BeginTimePeriodDt=B.BeginTimePeriodDt
and C.Service_Id=B.Service_Id

http://sqlfiddle.com/#!18/bac51/4

看更多先前的回應...收起先前的回應...
rogeryao iT邦研究生 5 級 ‧ 2018-10-06 14:36:16 檢舉

kenkotw iT邦新手 5 級 ‧ 2018-10-06 12:30:20 描述的需求又變了

CREATE TABLE LoginTime
([BeginTimePeriodDt] datetime, [User_Id] nvarchar(7), [Service_Id] nvarchar(8), [TotalLoginTime] int, [TotalIdleTime] int)
;
INSERT INTO LoginTime
([BeginTimePeriodDt], [User_Id],[Service_Id], [TotalLoginTime], [TotalIdleTime])
VALUES
('2018-10-02 09:30:00', 'sl10047','0', 720, 200),
('2018-10-02 09:30:00', 'sl10047','53000462', 720, 200),
('2018-10-02 09:30:00', 'sl10047','53000485', 720, 200),
('2018-10-02 09:30:00', 'sl10047','53000485', 720, 200),
('2018-10-02 09:30:00', 'sl10047','0', 720, 200),
('2018-10-02 09:30:00', 'sl10047','53000462', 720, 200),
('2018-10-02 09:30:00', 'sl10047','53000485', 720, 200),
('2018-10-02 09:30:00', 'sl10047','53000577', 720, 200),
('2018-10-02 09:45:00', 'sl10047','0', 900, 300),
('2018-10-02 09:45:00', 'sl10047','53000462', 900, 300),
('2018-10-02 09:45:00', 'sl10047','53000485', 900, 300),
('2018-10-02 09:45:00', 'sl10047','53000577', 900, 400),
('2018-10-02 10:00:00', 'sl10047','0', 900, 0),
('2018-10-02 10:00:00', 'sl10047','53000462', 900, 0),
('2018-10-02 10:00:00', 'sl10047','53000485', 900, 0),
('2018-10-02 10:00:00', 'sl10047','53000577', 900, 0),
('2018-10-02 10:15:00', 'sl10047','0', 900, 0),
('2018-10-02 10:15:00', 'sl10047','53000462', 900, 0),
('2018-10-02 10:15:00', 'sl10047','53000485', 900, 0),
('2018-10-02 10:15:00', 'sl10047','53000577', 900, 0)
;

select X.User_Id,X.TotalLoginTime,X.TotalIdleTime,Y.ServiceLoginTime,Y.ServiceIdleTime
from (
select MA.User_Id,
sum(isnull(MA.TotalLoginTime,0)) as TotalLoginTime,
sum(isnull(MA.TotalIdleTime,0)) as TotalIdleTime
from LoginTime as MA
where 1=1
and (MA.BeginTimePeriodDt>='2018-10-01' and MA.BeginTimePeriodDt <='2018-10-04')
and MA.Service_Id='0'
group by MA.User_Id
) as X
full outer join (
select B.User_Id,sum(isnull(B.TotalLoginTime,0)) as ServiceLoginTime,sum(isnull(B.TotalIdleTime,0)) as ServiceIdleTime
from LoginTime as B
inner join (
select A.User_Id,A.BeginTimePeriodDt,
max(A.Service_Id) as Service_Id
from LoginTime as A
where 1=1
and (A.BeginTimePeriodDt>='2018-10-01' and A.BeginTimePeriodDt <='2018-10-04')
and A.Service_Id <>'0'
and A.Service_Id <>'53000462'
group by A.User_Id,A.BeginTimePeriodDt) as C on C.User_Id=B.User_Id
and C.BeginTimePeriodDt=B.BeginTimePeriodDt
and C.Service_Id=B.Service_Id
where 1=1
group by B.User_Id
) as Y on Y.User_Id=X.User_Id
where 1=1
order by X.User_Id

暐翰 iT邦大師 5 級 ‧ 2018-10-06 15:05:46 檢舉

對,需求又變了...

rogeryao iT邦研究生 5 級 ‧ 2018-10-06 18:37:04 檢舉

修正
select X.User_Id,
改為
select
case when X.User_Id is null then Y.User_Id
else X.User_Id end as User_Id,

rogeryao iT邦研究生 5 級 ‧ 2018-10-06 18:46:05 檢舉

order by X.User_Id
改為
order by User_Id

kenkotw iT邦新手 5 級 ‧ 2018-10-08 09:37:20 檢舉

感謝各位的協助,我再試試看

kenkotw iT邦新手 5 級 ‧ 2018-10-08 15:16:10 檢舉

rogeryao 您好
我目前使用您提供語法是可以執行的
但目前有發現資料裏同一時間區段內在不同 service_id 會有不同的 Totallogintime,希望可以取 Totallogintime 最大值的那筆
我標示為粗體那筆 Totallogintime 改為 900 秒
語法應如可調整

('2018-10-02 09:30:00', 's110047', 0, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 720, 0),
('2018-10-02 09:30:00', 's110047', 53000462, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 720, 0),
('2018-10-02 09:30:00', 's110047', 53000485, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 900, 0),
('2018-10-02 09:30:00', 's110047', 53000577, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 720, 0),

目前的語法如下


select X.User_Id,X.TotalLoginTime,X.TotalIdleTime,Y.ServiceLoginTime,Y.ServiceIdleTime
from (
select MA.User_Id,
sum(isnull(MA.TotalLoginTime,0)) as TotalLoginTime,
sum(isnull(MA.TotalIdleTime,0)) as TotalIdleTime
--sum(case when (MA.service_id not in ('53000566','53000567')) then MA.TotalLoginTime else null end) as SACBLoginTime
--sum(case when (MA.service_id not in ('53000566','53000567')) then MA.TotalLoginTime else null end) as SACBidleTime
from AgentActivitySummary as MA
where 1=1
and (MA.BeginTimePeriodDt>='2018-10-03' and MA.BeginTimePeriodDt <='2018-10-04')
and MA.Service_Id='0'
group by MA.User_Id
) as X
full outer join (
select B.User_Id,sum(isnull(B.TotalLoginTime,0)) as ServiceLoginTime,sum(isnull(B.TotalIdleTime,0)) as ServiceIdleTime
from AgentActivitySummary as B
inner join (
select A.User_Id,A.BeginTimePeriodDt,
--max(A.totallogintime) as Service_Id
max(A.Service_Id) as Service_Id
from AgentActivitySummary as A
where 1=1
and (A.BeginTimePeriodDt>='2018-10-03' and A.BeginTimePeriodDt <='2018-10-04')
and A.Service_Id not in ('0','53000462','53000566','53000567','53000485') --不計算 MANUAL, SACB, AutoAgent
group by A.User_Id,A.BeginTimePeriodDt) as C on C.User_Id=B.User_Id
and C.BeginTimePeriodDt=B.BeginTimePeriodDt
--and C.totallogintime=B.totallogintime
and C.Service_Id=B.Service_Id
where 1=1
group by B.User_Id
) as Y on Y.User_Id=X.User_Id
where 1=1
order by X.User_Id


感謝您的協助

rogeryao iT邦研究生 5 級 ‧ 2018-10-08 20:52:04 檢舉

需求又變了......快猜不出來你要計算什麼了

假設需求為:每個User_ID在每個時間,不分登入那個Service_Id,其TotalLoginTime 及 TotalIdleTime 皆以最大值,計算總花費時間

CREATE TABLE AgentActivitySummary
([BeginTimePeriodDt] datetime, [User_id] varchar(7), [Service_Id] int, [LoginDt] datetime, [WorkGroup_Id] int, [EndTimePeriodDt] varchar(23)
, [Site_Id] int, [TenantId] int, [TotalLoginTime] int, [TotalIdleTime] int);

INSERT INTO AgentActivitySummary
([BeginTimePeriodDt], [User_id], [Service_Id], [LoginDt], [WorkGroup_Id], [EndTimePeriodDt], [Site_Id], [TenantId], [TotalLoginTime], [TotalIdleTime])
VALUES
('2018-10-02 09:30:00', 's110047', 0, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 720, 90),
('2018-10-02 09:30:00', 's110047', 53000462, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 720, 0),
('2018-10-02 09:30:00', 's110047', 53000485, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 900, 0),
('2018-10-02 09:30:00', 's110047', 53000486, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 900, 0),
('2018-10-02 09:30:00', 's110047', 53000487, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 900, 0),
('2018-10-02 09:30:00', 's110047', 53000577, '2018-10-02 09:32:59', 53000132, '2018-10-02 09:45:00.000', 54, 1, 720, 20)
;

select distinct V0.User_Id,
V1.TotalLoginTime,V2.TotalIdleTime,
V3.ServiceLoginTime,V4.ServiceIdleTime
from AgentActivitySummary as V0
-- A.Service_Id='0' & TotalLoginTime
left join
(
select K1.User_Id,
sum(K1.TotalLoginTime) as TotalLoginTime
from (
select
A.User_Id,A.BeginTimePeriodDt,
max(TotalLoginTime) as TotalLoginTime
from AgentActivitySummary as A
where 1=1
and (A.BeginTimePeriodDt>='2018-10-01' and A.BeginTimePeriodDt <='2018-10-04')
and A.Service_Id='0'
group by A.User_Id,A.BeginTimePeriodDt
) AS K1
where 1=1
Group by K1.User_Id
) as V1 on V1.User_Id=V0.User_Id
-- A.Service_Id='0' & TotalIdleTime
left join
(
select K2.User_Id,
sum(K2.TotalIdleTime) as TotalIdleTime
from (
select
A.User_Id,A.BeginTimePeriodDt,
max(TotalIdleTime) as TotalIdleTime
from AgentActivitySummary as A
where 1=1
and (A.BeginTimePeriodDt>='2018-10-01' and A.BeginTimePeriodDt <='2018-10-04')
and A.Service_Id='0'
group by A.User_Id,A.BeginTimePeriodDt
) AS K2
where 1=1
Group by K2.User_Id
) as V2 on V2.User_Id=V0.User_Id
-- A.Service_Id= other & ServiceLoginTime
left join
(
select K3.User_Id,
sum(K3.TotalLoginTime) as ServiceLoginTime
from (
select
A.User_Id,A.BeginTimePeriodDt,
max(TotalLoginTime) as TotalLoginTime
from AgentActivitySummary as A
where 1=1
and (A.BeginTimePeriodDt>='2018-10-01' and A.BeginTimePeriodDt <='2018-10-04')
and A.Service_Id not in ('0','53000462','53000566','53000567','53000485')
group by A.User_Id,A.BeginTimePeriodDt
) AS K3
where 1=1
Group by K3.User_Id
) V3 on V3.User_Id=V0.User_Id
-- A.Service_Id= other & ServiceIdleTime
left join
(
select K4.User_Id,
sum(K4.TotalIdleTime) as ServiceIdleTime
from (
select
A.User_Id,A.BeginTimePeriodDt,
max(TotalIdleTime) as TotalIdleTime
from AgentActivitySummary as A
where 1=1
and (A.BeginTimePeriodDt>='2018-10-01' and A.BeginTimePeriodDt <='2018-10-04')
and A.Service_Id not in ('0','53000462','53000566','53000567','53000485')
group by A.User_Id,A.BeginTimePeriodDt
) AS K4
where 1=1
Group by K4.User_Id
) V4 on V4.User_Id=V0.User_Id
order by V0.User_Id

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=678100406f83d6a85486202a21e94a45

rogeryao iT邦研究生 5 級 ‧ 2018-10-08 22:01:56 檢舉

或者是
select distinct V0.User_Id,
V1.TotalLoginTime,V1.TotalIdleTime,
V3.ServiceLoginTime,V3.ServiceIdleTime
from AgentActivitySummary as V0
-- A.Service_Id='0' & TotalLoginTime
left join
(
select K1.User_Id,
sum(K1.TotalLoginTime) as TotalLoginTime,sum(K1.TotalIdleTime) as TotalIdleTime
from (
select
A.User_Id,A.BeginTimePeriodDt,
max(TotalLoginTime) as TotalLoginTime,max(TotalIdleTime) as TotalIdleTime
from AgentActivitySummary as A
where 1=1
and (A.BeginTimePeriodDt>='2018-10-01' and A.BeginTimePeriodDt <='2018-10-04')
and A.Service_Id='0'
group by A.User_Id,A.BeginTimePeriodDt
) AS K1
where 1=1
Group by K1.User_Id
) as V1 on V1.User_Id=V0.User_Id
-- A.Service_Id= other & ServiceLoginTime
left join
(
select K3.User_Id,
sum(K3.TotalLoginTime) as ServiceLoginTime,sum(K3.TotalIdleTime) as ServiceIdleTime
from (
select
A.User_Id,A.BeginTimePeriodDt,
max(TotalLoginTime) as TotalLoginTime,max(TotalIdleTime) as TotalIdleTime
from AgentActivitySummary as A
where 1=1
and (A.BeginTimePeriodDt>='2018-10-01' and A.BeginTimePeriodDt <='2018-10-04')
and A.Service_Id not in ('0','53000462','53000566','53000567','53000485')
group by A.User_Id,A.BeginTimePeriodDt
) AS K3
where 1=1
Group by K3.User_Id
) V3 on V3.User_Id=V0.User_Id
order by V0.User_Id

rogeryao iT邦研究生 5 級 ‧ 2018-10-09 00:01:24 檢舉

SQL 語法無誤 , 測試資料 s110047 <= 字串有 key 錯

kenkotw iT邦新手 5 級 ‧ 2018-10-09 10:30:10 檢舉

暐翰 & rogeryao
我看懂了,也學了很多
感謝各位的協助

我要發表回答

立即登入回答