从一个 table 获取所有日期并从另一个 table 获取每个日期的总记录
Get all dates from one table and get total records of each date from another table
我创建了一个存储过程,它将接受 startdate
、enddate
、timezone
、user
和 host
并将显示给定日期范围内每一天的所有记录数。
我已经使用 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
在您的查询中(并且很可能也按此分组)。
我创建了一个存储过程,它将接受 startdate
、enddate
、timezone
、user
和 host
并将显示给定日期范围内每一天的所有记录数。
我已经使用 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
在您的查询中(并且很可能也按此分组)。