简体   繁体   English

带有数据透视表的动态SQL过程根据日期范围显示计数

[英]Dynamic SQL Procedure with Pivot displaying counts based on Date Range

表

I have a table which contains multiple user entries. 我有一个包含多个用户条目的表。 I want to pull counts of user entries based on date range passed to a stored procedure. 我想根据传递给存储过程的日期范围提取用户条目数。

start date: 11/9/2017 end date: 11/11/2017 开始日期:11/9/2017结束日期:11/11/2017

However the response needs to be dynamic based on amount of days in the date range. 但是,响应必须根据日期范围内的天数而动态变化。

Here is a desired format: 这是所需的格式: 格式照片

If you are using MySQL this will make what you want: 如果您使用的是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

If you are using SQL Server, you could try it with PIVOT: 如果您使用的是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

Now that you have provided examples, I have updated my answer which provides you with a solution based on the data you have provided. 现在,您已经提供了示例,我已经更新了答案,该答案将根据您提供的数据为您提供解决方案。

Note that you are able to change the date range and the query will update accordingly. 请注意,您可以更改日期范围,查询也会相应更新。

Bare in mind that this SQL query is for SQL Server: 切记此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;

Let me know if that's what you were looking for. 让我知道您是否在寻找。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM