我希望获得两个日期arrival date
和leaving date
之间的所有日期。
我尝试了递归查询,但它没有用。
;with dates as (
SELECT GuestID, ArrivalDate as reserveddate
from dbo.Guest
union all
SELECT GuestID, dateadd (day,1,dbo.Guest. ArrivalDate) as reserveddate
from dbo.Guest
where dateadd (day,1,dbo.Guest. ArrivalDate) <dbo.Guest.leavingate
)
SELECT *
from dates
option (maxrecursion 0)
答案 0 :(得分:2)
您需要递归CTE:
int[] a = { 1, 5, 8 };
int[] b = { 6, 9 };
int aPos = 0;
int bPos = 0;
int n = a.length + b.length;
int[] result = new int[n];
for (int i = 0; i < n; i++) {
if (aPos == a.length) {
// at end of A, must use B
result[i] = b[bPos++];
} else if (bPos == b.length) {
// at end of B, must use A
result[i] = a[aPos++];
} else if (a[aPos] < b[bPos]) {
result[i] = a[aPos++];
} else {
result[i] = b[bPos++];
}
}
System.out.println(Arrays.toString(result));
输出:
DECLARE @arrival_date date = '2016-01-01',
@leaving_date date = '2016-02-01'
;WITH cte AS (
SELECT @arrival_date as date_
UNION ALL
SELECT CAST(DATEADD(day,1,date_) as date)
FROM cte
WHERE date_ < @leaving_date
)
SELECT *
FROM cte
OPTION (MAXRECURSION 0)
<强> EDIT1 强>
根据您的样本:
date_
2016-01-01
2016-01-02
2016-01-03
...
2016-01-30
2016-01-31
2016-02-01
<强> EDIT2 强>
;WITH cte AS (
SELECT GuestID, CAST(ArrivalDate as date) as date_
FROM Guests
UNION ALL
SELECT c.GuestID, CAST(DATEADD(day,1,date_) as date)
FROM cte c
INNER JOIN Guests g
ON g.GuestID = c.GuestID
WHERE date_ < g.LeavingDate
)
SELECT *
FROM cte
ORDER BY GuestID, date_
OPTION (MAXRECURSION 0)
输出:
;WITH Guests AS (
SELECT 1 as GuestID,
'2016-01-01' ArrivalDate,
'2016-01-05' LeavingDate
UNION ALL
SELECT 2 ,
'2016-06-17',
'2016-06-20'
), cte AS (
SELECT GuestID, CAST(ArrivalDate as date) as date_
FROM Guests
UNION ALL
SELECT c.GuestID, CAST(DATEADD(day,1,date_) as date)
FROM cte c
INNER JOIN Guests g
ON g.GuestID = c.GuestID
WHERE date_ < g.LeavingDate
)
SELECT *
FROM cte
ORDER BY GuestID, date_
OPTION (MAXRECURSION 0)
答案 1 :(得分:1)
我喜欢这种类型的东西是使用计数表。我对每个看起来像这样的系统都有所了解。
data.frame
通过这种方式,我总能随时随地拿着一张理货桌。您可以在此处阅读有关计数表以及它们如何替换循环的更多信息。 http://www.sqlservercentral.com/articles/T-SQL/62867/
要解决您当前的问题,这变得相当简单。首先,我们需要一个表格和一些样本数据。
create View [dbo].[cteTally] as
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N from cteTally
GO
这是理货桌真正显示的力量所在。为挑战生成输出就像这段代码一样简单。
create table #Guest
(
GuestID int identity
, ArrivalDate date
, DepartureDate date
)
insert #Guest
select '2016-06-01', '2016-06-15' union all
select '2016-07-01', '2016-07-12'
这种方法相对于递归cte的另一大优势是,您使用的是所谓的三角形连接,可能会导致一些性能挑战。以下是有关三角形连接的更多信息。 http://www.sqlservercentral.com/articles/T-SQL/61539/
答案 2 :(得分:0)
试试这个
DECLARE @DateFrom DateTime = DATEADD(DAY,DATEDIFF(DAY,0,GETDATE())-5,0)
DECLARE @DateTo DateTime = CONVERT(DATE,GETDATE())
;WITH Numbers (Number) AS (
SELECT row_number() OVER (ORDER BY object_id)
FROM sys.all_objects
)
SELECT dateadd(DAY, number-1, @DateFrom)
FROM Numbers
WHERE number <= datediff(DAY, @DateFrom-1, @DateTo-1)
您可以通过在选择日期和日期中更改DAY到WEEK,MONTH,YEAR等来更改日期间隔