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

Get all dates from one table and get total records of each date from another table

我创建了一个存储过程,它将接受 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] 是一个用户定义的函数,它将 return 一个 table 具有特定日期范围内的所有日期,如下所示:

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 年 2 月 5 日之间每天的记录数,结果应该是

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

但我的程序是return像这样

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

我做错了什么?

a.DateTime 是左连接的右侧,因此可能 return 为空值。看来您想要联接的左侧,即 b.thedate。因此,您应该 select b.thedate 而不是 a.DateTime 在您的查询中(并且很可能也按此分组)。