【问题标题】:SQL select everything in date range with multiple values for each dateSQL选择日期范围内的所有内容,每个日期都有多个值
【发布时间】:2014-12-09 12:01:21
【问题描述】:

我已经尝试过搜索,但如果这已经在其他地方得到了回答,我不完全确定如何措辞所以提前道歉。

我正在尝试为多个值选择日期范围之间的所有内容(包括该日期没有值的地方)。我还没有真正解释清楚,但下面是我所追求的输出示例。

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

【问题讨论】:

  • 我目前已经使用下面的代码创建了一个静态表。这将是再次需要的东西,因此认为拥有一个静态表是有意义的。 CREATE TABLE _Dates ( d DATE, PRIMARY KEY (d) ) DECLARE @dIncr DATE = '2000-01-01' DECLARE @dEnd DATE = '2100-01-01' WHILE ( @dIncr &lt; @dEnd ) BEGIN INSERT INTO _Dates (d) VALUES( @dIncr ) SELECT @dIncr = DATEADD(DAY, 1, @dIncr ) END

标签: sql sql-server date


【解决方案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
  • 这是我目前用来获取返回日期值的方法。不过,我无法弄清楚如何为每个可能的结果返回日期。例如,我需要在 1 月 1 日返回每个活动、每个可能的交易类型和每个销售渠道。我是否需要为每个结果创建带有一行的表格并将其加入我的数据集?
  • 与您的活动表完全外部联接,然后才加入您的结果
【解决方案2】:

如果使用纯 SQL(并且没有递归 CTE),恐怕您需要a numbers table

基本思路是:

  • 确定n,您的开始日期和结束日期之间的日期数,
  • 从数字表中选择数字 1 到 n,然后
  • 将数字(以天为单位)添加到开始日期。

这应该会产生从开始日期到结束日期的日期列表,您可以将其外部连接到原始结果集以“填补空白”。

【讨论】:

    【解决方案3】:

    我正在使用返回某个范围内所有日期的表值函数 (here)..

    您可以进行一些小的更改(如重命名、日期时间 -> 日期、删除 char 列)以满足您的需求。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多