[英]Dynamic SQL Procedure with Pivot displaying counts based on Date Range
我有一個包含多個用戶條目的表。 我想根據傳遞給存儲過程的日期范圍提取用戶條目數。
開始日期:11/9/2017結束日期:11/11/2017
但是,響應必須根據日期范圍內的天數而動態變化。
這是所需的格式:
如果您使用的是MySQL,這將滿足您的要求:
SELECT UserID,
UserName,
SUM(Date = '2017-11-09') '2017-11-09',
SUM(Date = '2017-11-10') '2017-11-10',
SUM(Date = '2017-11-11') '2017-11-11'
FROM src
GROUP BY UserID
如果您使用的是SQL Server,則可以使用PIVOT進行嘗試:
SELECT *
FROM
(SELECT userID, userName, EntryDateTime
FROM t) src
PIVOT
(COUNT(userID)
FOR EntryDateTime IN (['2017-11-09'], ['2017-11-10'], ['2017-11-11'])) pvt
現在,您已經提供了示例,我已經更新了答案,該答案將根據您提供的數據為您提供解決方案。
請注意,您可以更改日期范圍,查詢也會相應更新。
切記此SQL查詢適用於SQL Server:
create table #tbl1 (
[UserId] int
,[UserName] nvarchar(max)
,[EntryDateTime] datetime
);
insert into #tbl1 ([UserId],[UserName],[EntryDateTime])
values
(1,'John Doe','20171109')
,(1,'John Doe','20171109')
,(1,'John Doe','20171110')
,(1,'John Doe','20171111')
,(2,'Mike Smith','20171109')
,(2,'Mike Smith','20171110')
,(2,'Mike Smith','20171110')
,(2,'Mike Smith','20171110')
;
-- declare variables
declare
@p1 date
,@p2 date
,@diff int
,@counter1 int
,@counter2 int
,@dynamicSQL nvarchar(max)
;
-- set variables
set @p1 = '20171109'; -- ENTER THE START DATE IN THE FORMAT YYYYMMDD
set @p2 = '20171111'; -- ENTER THE END DATE IN THE FORMAT YYYYMMDD
set @diff = datediff(dd,@p1,@p2); -- used to calculate the difference in days
set @counter1 = 0; -- first counter to be used in while loop
set @counter2 = 0; -- second counter to be used in while loop
set @dynamicSQL = 'select pivotTable.[UserId] ,pivotTable.[UserName] as [Name] '; -- start of the dynamic SQL statement
-- to get the dates into the query in a dynamic way, you need to do a while loop (or use a cursor)
while (@counter1 < @diff)
begin
set @dynamicSQL += ',pivotTable.[' + convert(nvarchar(10),dateadd(dd,@counter1,@p1),120) + '] '
set @counter1 = (@counter1 +1)
end
-- continuation of the dynamic SQL statement
set @dynamicSQL += ' from (
select
t.[UserId]
,t.[UserName]
,cast(t.[EntryDateTime] as date) as [EntryDate]
,count(t.[UserId]) as [UserCount]
from #tbl1 as t
where
t.[EntryDateTime] >= ''' + convert(nvarchar(10),@p1,120) + ''' ' +
' and t.[EntryDateTime] <= ''' + convert(nvarchar(10),@p2,120) + ''' ' +
'group by
t.[UserId]
,t.[UserName]
,t.[EntryDateTime]
) as mainQuery
pivot (
sum(mainQuery.[UserCount]) for mainQuery.[EntryDate]
in ('
;
-- the second while loop which is used to create the columns in the pivot table
while (@counter2 < @diff)
begin
set @dynamicSQL += ',[' + convert(nvarchar(10),dateadd(dd,@counter2,@p1),120) + ']'
set @counter2 = (@counter2 +1)
end
-- continuation of the SQL statement
set @dynamicSQL += ')
) as pivotTable'
;
-- this is the easiet way I could think of to get rid of the leading comma in the query
set @dynamicSQL = replace(@dynamicSQL,'in (,','in (');
print @dynamicSQL -- included this so that you can see the SQL statement that is generated
exec sp_executesql @dynamicSQL; -- this will run the generate dynamic SQL statement
drop table #tbl1;
讓我知道您是否在尋找。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.