从一个表中获取所有日期,并从另一个表中获取每个日期的总记录

时间:2015-02-24 05:52:41

标签: sql sql-server datetime stored-procedures

我创建了一个存储过程,接受startdateenddatetimezoneuserhost

并将显示给定日期范围内每天所有记录的计数。

我使用LEFT OUTER JOIN为我创建了一个存储过程,以下是我的代码:

USE [database]
GO
/****** Object:  StoredProcedure [dbo].[sp_getPageViewCountDayWise]           Script Date: 24/02/2015 10:25:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_getPageViewCountDayWise]

    -- Add the parameters for the stored procedure here
   --<@Param1, sysname, @p1> <Datatype_For_Param1, , int> = <Default_Value_For_Param1, , 0>,
    --<@Param2, sysname, @p2> <Datatype_For_Param2, , int> = <Default_Value_For_Param2, , 0>

    @startdate DATETIME,
    @enddate DATETIME,
    @timezone VARCHAR(6),
    @user varchar(500),
    @host VARCHAR(200)

AS
BEGIN

    SET NOCOUNT ON;

    IF NULLIF(@user, '') IS NULL
    begin 
        set @user = @host+'/%'
    end 
    else
    begin
        set @user = @host+'/'+@user+'/%'
    end

   select * from [dbo].[ExplodeDates](@startdate,@enddate)

    select CAST(a.DateTime AS DATE) AS Date, count(*) as count
    from [dbo].[DateRange](@startdate,@enddate) AS b 
    LEFT OUTER JOIN UserLog AS a
    ON CAST(b.thedate AS DATE) = CAST(dbo.[ConvertDateToFromTimeZone]   (a.DateTime, @timezone) AS DATE) 
   and a.Url like @user
    group by CAST(a.DateTime AS date)

   END

[dbo].[DateRange]是一个用户定义的函数,它将返回一个表,其中包含特定日期范围内的所有日期,如下所示:

GO
/****** Object:  UserDefinedFunction [dbo].[ExplodeDates]    Script Date:       24/02/2015 11:12:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[ExplodeDates](@startdate datetime, @enddate   datetime)
returns table as
return (
with 
 N0 as (SELECT 1 as n UNION ALL SELECT 1)
,N1 as (SELECT 1 as n FROM N0 t1, N0 t2)
,N2 as (SELECT 1 as n FROM N1 t1, N1 t2)
,N3 as (SELECT 1 as n FROM N2 t1, N2 t2)
,N4 as (SELECT 1 as n FROM N3 t1, N3 t2)
,N5 as (SELECT 1 as n FROM N4 t1, N4 t2)
,N6 as (SELECT 1 as n FROM N5 t1, N5 t2)
,nums as (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as num FROM N6)
SELECT DATEADD(day,num-1,@startdate) as thedate
FROM nums
WHERE num <= DATEDIFF(day,@startdate,@enddate) + 1
);

dbo.[ConvertDateToFromTimeZone]是一个将每个日期转换为给定时区的函数

GO
/****** Object:  UserDefinedFunction [dbo].[ConvertDateToFromTimeZone]       Script Date: 24/02/2015 11:14:03 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[ConvertDateToFromTimeZone]
(
   -- Add the parameters for the function here
    @date DATETIMEOFFSET,
    @offset VARCHAR(6)
)
RETURNS DATETIME
AS
BEGIN
   -- Declare the return variable here
   DECLARE @Result DATETIME

   -- Add the T-SQL statements to compute the return value here
    SELECT @Result= SWITCHOFFSET (@date , @offset)
    -- Return the result of the function
    RETURN @Result

END

假设我想查看2015年2月2日至2015年5月5日之间的记录数量,结果应为

Date        Count
02/02/2015    10
03/02/2015     2
04/02/2015     0
05/02/2015     3

但是我的程序正在返回类似这样的内容

Date          Count
NULL           2
02/02/2015     10
03/02/2015     2
05/02/2015     3

我做错了什么?

1 个答案:

答案 0 :(得分:1)

a.DateTime是左连接的右侧,因此可以返回空值。您似乎想要联接的左侧,即b.thedate。因此,您应该在查询中选择b.thedate而不是a.DateTime(而且很可能也会选择此组)。