Tôi cho rằng đối với mục đích cụ thể này, truy vấn dưới đây hiệu quả như sử dụng bảng tra cứu chuyên dụng.
DECLARE @start DATE, @end DATE;
SELECT @start = '20110714', @end = '20110717';
;WITH n AS
(
SELECT TOP (DATEDIFF(DAY, @start, @end) + 1)
n = ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_objects
)
SELECT 'Bob', DATEADD(DAY, n-1, @start)
FROM n;
Kết quả:
Bob 2011-07-14
Bob 2011-07-15
Bob 2011-07-16
Bob 2011-07-17
Có lẽ bạn sẽ cần điều này như là một tập, chứ không phải cho một thành viên duy nhất, vì vậy đây là một cách để thích nghi với kỹ thuật này:
DECLARE @t TABLE
(
Member NVARCHAR(32),
RegistrationDate DATE,
CheckoutDate DATE
);
INSERT @t SELECT N'Bob', '20110714', '20110717'
UNION ALL SELECT N'Sam', '20110712', '20110715'
UNION ALL SELECT N'Jim', '20110716', '20110719';
;WITH [range](d,s) AS
(
SELECT DATEDIFF(DAY, MIN(RegistrationDate), MAX(CheckoutDate))+1,
MIN(RegistrationDate)
FROM @t -- WHERE ?
),
n(d) AS
(
SELECT DATEADD(DAY, n-1, (SELECT MIN(s) FROM [range]))
FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_objects) AS s(n)
WHERE n <= (SELECT MAX(d) FROM [range])
)
SELECT t.Member, n.d
FROM n CROSS JOIN @t AS t
WHERE n.d BETWEEN t.RegistrationDate AND t.CheckoutDate;
----------^^^^^^^ not many cases where I'd advocate between!
Kết quả:
Member d
-------- ----------
Bob 2011-07-14
Bob 2011-07-15
Bob 2011-07-16
Bob 2011-07-17
Sam 2011-07-12
Sam 2011-07-13
Sam 2011-07-14
Sam 2011-07-15
Jim 2011-07-16
Jim 2011-07-17
Jim 2011-07-18
Jim 2011-07-19
Như @Dems chỉ ra, điều này có thể được đơn giản hóa để:
;WITH natural AS
(
SELECT ROW_NUMBER() OVER (ORDER BY [object_id]) - 1 AS val
FROM sys.all_objects
)
SELECT t.Member, d = DATEADD(DAY, natural.val, t.RegistrationDate)
FROM @t AS t INNER JOIN natural
ON natural.val <= DATEDIFF(DAY, t.RegistrationDate, t.CheckoutDate);
Có một cái nhìn ở đây http://stackoverflow.com/questions/1478951/tsql-generate-a-resultset-of-incrementing-dates [1]: http: // stackoverflow .com/questions/1478951/tsql-generate-a-resultset-of-incrementing-date – StoicFnord
Nói chung, bạn không. Bạn có một bảng tra cứu và chọn chúng ra khỏi đó. 'WHERE calendar.date> = user.start_date AND calendar.date <= user.leave_date' Bạn * CAN * tạo tập hợp bằng cách sử dụng vòng lặp hoặc truy vấn đệ quy, nhưng chúng không bao giờ nhanh bằng cách sử dụng bảng tra cứu. – MatBailie
Tôi hỏi một câu hỏi rất giống, nhưng tôi là giờ, không phải ngày. Bạn có thể thay đổi để phù hợp với nhu cầu của bạn khá dễ dàng. http://stackoverflow.com/questions/10986344/get-every-hour-for-a-time-range – Limey