Sql server 在两个日期之间每天输出一行

Sql server 在两个日期之间每天输出一行,sql-server,tsql,Sql Server,Tsql,想象一下,一家旅馆的住客搬进/搬出不同的房间。该信息作为占用率表中的一行存储在数据库中 例如,1000号乘客于3月3日到达,并于3月5日入住100号床。他们在4月2日再次回来,呆在101号床上。乘客1001于4月1日在100号床上停留了一晚 我需要按入住者和床位为入住和迁出日期之间的每天生成一行 以下是当前数据的外观: +------------+-------+------------+-------------+ | OccupantID | BedID | MoveInDate | Mov

想象一下,一家旅馆的住客搬进/搬出不同的房间。该信息作为占用率表中的一行存储在数据库中

例如,1000号乘客于3月3日到达,并于3月5日入住100号床。他们在4月2日再次回来,呆在101号床上。乘客1001于4月1日在100号床上停留了一晚

我需要按入住者和床位为入住和迁出日期之间的每天生成一行

以下是当前数据的外观:

+------------+-------+------------+-------------+ | OccupantID | BedID | MoveInDate | MoveOutDate | +------------+-------+------------+-------------+ | 1000 | 100 | 3/3/2016 | 3/5/2016 | | 1000 | 101 | 4/2/2016 | 4/3/2016 | | 1001 | 100 | 4/1/2016 | 4/1/2016 | +------------+-------+------------+-------------+ 下面是所需输出的样子

+------------+-------+----------+ | OccupantID | BedID | Date | +------------+-------+----------+ | 1000 | 100 | 3/3/2016 | | 1000 | 100 | 3/4/2016 | | 1000 | 100 | 3/5/2016 | | 1000 | 101 | 4/2/2016 | | 1000 | 101 | 4/3/2016 | | 1001 | 100 | 4/1/2016 | +------------+-------+----------+
您可以借助以下工具完成此操作:


您可以使用以下TSQL来执行此操作:


试试这个,不需要任何配分函数

declare @t table (OccupantID int,BedID int, MoveInDate date, MoveOutDate date)
insert into @t values
(1000,100,'3/3/2016','3/5/2016')
,(1000,101,'4/2/2016','4/3/2016')
,(1001,100,'4/1/2016','4/1/2016')

;WITH CTE
AS (
    SELECT OccupantID
        ,BedID
        ,MoveInDate [StayDate]
    FROM @t

    UNION ALL

    SELECT a.OccupantID
        ,a.BedID
        ,dateadd(day, 1, b.StayDate)
    FROM @t A
    INNER JOIN CTE B ON a.OccupantID = b.OccupantID
        AND a.BedID = b.BedID
    WHERE b.StayDate < a.MoveOutDate
    )
SELECT *
FROM CTE
ORDER BY OccupantID
    ,bedid

您能否生成一个填充了日期的日期帮助表,然后将这两个表连接起来,例如从Occupant中选择*o在o.MoveinDate和o.MoveOutDate之间的h.date上加入帮助程序h.date?@cqi-谢谢您的提示,我发现它非常有用,因为我现在有大量的数据,每天都可以使用helper表提取。宾果-你答对了。谢谢你的回复。我也将测试这个方法。
--create table occupancy
--(OccupantID int,BedID int,MoveInDate date,MoveOutDate  date);
--insert into occupancy values
--(1000,100,'3/3/2016','3/5/2016'),
--(1000,101,'4/2/2016','4/3/2016'),
--(1001,100,'4/1/2016','4/1/2016');

create table #t(OccupantID int,BedID int,OccupiedDate date);
create table #temp (id int,OccupantID int,BedID int,MoveInDate date,MoveOutDate  date);
insert into #temp
select 
row_number() over( order by occupantId,moveinDate desc) id, occupantid,bedid,moveindate, moveoutdate from occupancy
Declare @c int
Declare @startdate date, @enddate date
Select @c=MAX(id) from #temp
WHILE(@c>0)
BEGIN
SELECT @startdate=MoveinDate, @enddate=Moveoutdate from #temp where id=@c
INSERT INTO #t
SELECT occupantid,bedid,@startdate from #temp where id=@c
    WHILE (@startdate<@enddate)
    BEGIN
        SET @startdate=DATEADD(d,1,@startdate)
        INSERT INTO #t
        SELECT occupantid,bedid,@startdate from #temp where id=@c
    END
SET @c=@c-1
END

select * from #t
drop table #temp,#t
declare @t table (OccupantID int,BedID int, MoveInDate date, MoveOutDate date)
insert into @t values
(1000,100,'3/3/2016','3/5/2016')
,(1000,101,'4/2/2016','4/3/2016')
,(1001,100,'4/1/2016','4/1/2016')

;WITH CTE
AS (
    SELECT OccupantID
        ,BedID
        ,MoveInDate [StayDate]
    FROM @t

    UNION ALL

    SELECT a.OccupantID
        ,a.BedID
        ,dateadd(day, 1, b.StayDate)
    FROM @t A
    INNER JOIN CTE B ON a.OccupantID = b.OccupantID
        AND a.BedID = b.BedID
    WHERE b.StayDate < a.MoveOutDate
    )
SELECT *
FROM CTE
ORDER BY OccupantID
    ,bedid