我已经尝试过搜索,但我不完全确定如果在其他地方已经回答了这个问题,请提前道歉。
我正在尝试选择多个值的日期范围(包括该日期没有值的地方)之间的所有内容。我还没有真正解释过,但下面是我所追求的输出的一个例子。
Date Campaign Channel Transaction
01/01/2015 a Online Sale
01/01/2015 b Online Sale
01/01/2015 c Online Sale
01/01/2015 a Online Cancellation
01/01/2015 b Online Cancellation
01/01/2015 c Online Cancellation
01/01/2015 a Offline Sale
01/01/2015 b Offline Sale
01/01/2015 c Offline Sale
01/01/2015 a Offline Cancellation
01/01/2015 b Offline Cancellation
01/01/2015 c Offline Cancellation
02/01/2015 a Online Sale
02/01/2015 b Online Sale
02/01/2015 c Online Sale
02/01/2015 a Online Cancellation
02/01/2015 b Online Cancellation
02/01/2015 c Online Cancellation
02/01/2015 a Offline Sale
02/01/2015 b Offline Sale
02/01/2015 c Offline Sale
02/01/2015 a Offline Cancellation
02/01/2015 b Offline Cancellation
02/01/2015 c Offline Cancellation
我可以选择日期范围之间的每一天,但是即使没有返回任何结果,也无法确定如何选择每一天的结果。
编辑 - 添加了我找到的解决方案
好的,所以我有一个似乎对我有用的解决方案。可能有更好的方法来做到这一点,任何建议都表示赞赏,但这是我现在正在做的事情
Declare @CC TABLE (Campaign varchar(50))
DECLARE @Channel Table (Channel Varchar(255))
DECLARE @TYPE TABLE (Transaction_Type varchar(255))
Insert Into @CC (Campaign) Values ('1')
Insert Into @CC (Campaign) Values ('2')
Insert Into @Channel (Channel) Values ('Online')
Insert Into @Channel (Channel) Values ('Inbound')
Insert Into @TYPE (Transaction_Type) Values ('Sale')
Insert Into @TYPE (Transaction_Type) Values ('Cancellation')
DECLARE
@StartDate DATE = Dateadd(YY,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)),
@EndDate DATE = Getdate()
SELECT
DATEADD(DAY, nbr - 1, @StartDate) as Dates,
Campaign,
Channel,
Transaction_Type
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
FROM sys.columns c) nbrs,
@CC, @Channel, @TYPE WHERE nbr - 1 <= DATEDIFF(DAY, @StartDate, @EndDate)
Order by Dates asc, Campaign asc, Channel asc, Transaction_Type asc
答案 0 :(得分:1)
您可以使用CTE进行此操作。
DECLARE
@start date = '1900-01-01',
@end date = '1900-01-10';
with dateRange (myDate) AS (
select @start myDate
UNION ALL
select DATEADD(DAY,1,myDate) from dateRange
where
myDate <= @end
)
select
*
from dateRange D
inner join yourTable T on
D.myDate = T.[Date]
OPTION (MAXRECURSION 365)
使用完整的外连接
DECLARE
@start date = '1900-01-01',
@end date = '1900-01-10';
with dateRange (myDate) AS (
select @start myDate
UNION ALL
select DATEADD(DAY,1,myDate) from dateRange
where
myDate <= @end
)
select
*
from dateRange D
full outer join @CC C ON
1=1
full outer join @Channel CH ON
1=1
full outer join @TYPE Ty ON
1=1
left join yourTable T on
D.myDate = T.[Date] and
C.Campaign = T.[Campaign] and
CH.Channel = T.[Channel] and
Ty.[Transaction_Type] = T.[Transaction_Type]
OPTION (MAXRECURSION 365)
答案 1 :(得分:0)
使用纯SQL(并且没有递归CTE),我担心你需要a numbers table。
基本理念是:
n
,即开始日期和结束日期之间的日期数,n
,然后这应该会生成从开始日期到结束日期的日期列表,您可以将其加入到原始结果集中以填补空白&#34;。
答案 2 :(得分:0)
我正在使用表值函数返回范围(here)中的所有日期。
您可以进行小的更改(例如重命名,日期时间 - &gt;日期,删除字符列)以满足您的需求。
Create Function [dbo].[IntervalaDatumi]
(
@DatumsNo DateTime,
@DatumsLidz DateTime
)
Returns @tab Table
(
Datums DateTime,
DatumsChar char(10)
)
As
Begin
Declare @Dienas int
Declare @i int
Set @Dienas = DateDiff(Day, @DatumsNo, @DatumsLidz)
Set @i = 0;
While (@Dienas > @i)
Begin
Insert Into @tab(Datums, DatumsChar)
Values (DateAdd(Day, @i, @DatumsNo), Convert(Char(10), DateAdd(Day, @i, @DatumsNo), 104))
Set @i = @i + 1
End
return
End