2012-06-11 43 views
5

Vì vậy, những gì tôi đang cố gắng tạo ra tất cả các giờ nằm ​​trong một phạm vi thời gian cụ thể.Nhận mỗi giờ trong một khoảng thời gian

Vì vậy, cho phạm vi 11:00-2:00, tôi sẽ nhận được:

11:00 AM 
12:00 PM 
1:00 PM 
2:00 PM 

Tôi cố gắng để tránh việc để lưu trữ tất cả các giờ cụ thể một cửa hàng có thể mở và lưu trữ chỉ phạm vi (I cần phải so sánh giờ chống lại những thời điểm khác)

Cảm ơn

+2

Chỉ lưu 'OpenTime' và' ClosedTime' trong db và so sánh mã của bạn?!?! –

+0

Phiên bản SQL Server nào? – Lamak

+0

@Lamak: 2008 r2 – Limey

Trả lời

5

Nếu bạn có một numbers table (nhấp vào liên kết để tạo ra một nếu bạn không) ...

create table test(
    startTime time 
, endTime time 
) 

insert into test 
select '11:00', '14:00' 

select 
    dateadd(hh, n.n, t.startTime) as times 
from test t 
    inner join Numbers n 
    -- assuming your numbers start at 1 rather than 0 
    on n.n-1 <= datediff(hh, t.startTime, t.endTime) 

Nếu đây là chuyên môn, bạn có thể tạo bảng giờ chỉ với 24 giá trị.

create table HoursInADay(
    [hours] time not null 
, constraint PK_HoursInADay primary key ([hours]) 
) 

-- insert 
insert into HoursInADay select '1:00' 
insert into HoursInADay select '2:00' 
insert into HoursInADay select '3:00' 
insert into HoursInADay select '4:00' 
insert into HoursInADay select '5:00' 
insert into HoursInADay select '6:00' 
insert into HoursInADay select '7:00' 
... 

select 
    h.[hours] 
from test t 
    inner join HoursInADay h 
    on h.[hours] between t.startTime and t.endTime 
+1

@David Hơi khác một chút. Câu trả lời ban đầu của tôi cũng cho biết tạo bảng giờ làm tùy chọn nhưng tôi không bao gồm ví dụ để hiển thị cách hoạt động của bảng. Xin lỗi nếu có vẻ như tôi đã đánh cắp đề xuất của bạn. – Zhenny

+0

Xin lỗi. Có vẻ như bạn đã tạo ra câu trả lời, sau khi nhìn thấy câu trả lời của tôi, bạn đã thay đổi ý định và đưa ra câu trả lời. Tôi xin lỗi. –

4

cách đơn giản nhất tôi có thể nghĩ ra để làm điều này là để chỉ có 1 bảng vĩnh viễn với một danh sách của tất cả các giờ; Tổng cộng 24 mục.

Create table dbo.Hours (Hourly_Time Time NOT NULL) 
Insert into dbo.Hours ... 

Sau đó, lần trao Một & B:

select * from dbo.Hours where Hourly_Time<=A and Hourly_Time>=B 
+1

Tôi thích ý tưởng này, tôi sẽ thực hiện điều này. – Limey

+0

'= <' and '=>'? –

+0

Tôi biết ý nghĩa của chúng; bạn đã thử cú pháp bạn thực sự đăng chưa? 'IF 1 = <2 PRINT 'um';' sản lượng 'Msg 102, Cấp 15, Tiểu bang 1, Dòng 1 Cú pháp không đúng gần '<'.' –

7

Bạn có thể sử dụng CTE đệ quy. Điều này sẽ tạo ra những giờ giữa 11 và 14:

;with Hours as 
     (
     select 11 as hr 
     union all 
     select hr + 1 
     from Hours 
     where hr < 14 
     ) 
select * 
from Hours 

Live example at SQL Fiddle.

+0

Tôi thích nó nhất, nhưng nó trả về một int và không phải là một thời gian, nhưng tôi chắc chắn rằng tôi có thể sửa đổi để làm việc với một thời gian – Limey

+0

@AaronBertrand: yeah, tôi có nghĩa là int và thời gian, tôi chỉnh sửa bình luận của tôi. – Limey

11

Không vòng, CTEs đệ quy hoặc số bảng yêu cầu.

DECLARE 
    @start TIME(0) = '11:00 AM', 
    @end TIME(0) = '2:00 PM'; 

WITH x(n) AS 
(
    SELECT TOP (DATEDIFF(HOUR, @start, @end) + 1) 
    rn = ROW_NUMBER() OVER (ORDER BY [object_id]) 
    FROM sys.all_columns ORDER BY [object_id] 
) 
SELECT t = DATEADD(HOUR, n-1, @start) FROM x ORDER BY t; 
+2

Tôi luôn cảm thấy mỏng manh khi sử dụng các bảng sys theo cách này. Nó cảm thấy một chút tin tặc. – Zhenny

+1

@ Zhenny Vâng, tôi thích một bảng 'Numbers' cá nhân, nhưng cho đến khi một tàu với SQL Server, hãy thử và thuyết phục tất cả mọi người để tạo ra một. [Hãy bình chọn và bình luận, có lẽ chúng tôi sẽ nhận được một trong phiên bản tiếp theo] (http://connect.microsoft.com/SQLServer/feedback/details/258733/add-a-built-in-table-of-numbers) ! –

+1

Có cách nào giải pháp này có thể được sửa đổi để tính toán thay đổi trong ngày không? Ví dụ: nếu bạn muốn mỗi giờ từ 11 giờ tối đến 2 giờ sáng Thứ Ba –

0

@Andomar Cảm ơn rất nhiều, bạn đã giúp tôi, có phần bổ sung của tôi ở trên mã của bạn.

*---------------------------- 

create view vw_hoursalot as 
    with Hours as 
    (
     select DATEADD(
     dd, 0, DATEDIFF(
       dd, 0, DATEADD (
        year , -5 , getDate() 
       ) 
      ) 
    ) as dtHr 
    union all 
     select DATEADD (minute , 30 , dtHr) 
     from Hours 
     where dtHr < DATEADD(
      dd, 0, DATEDIFF(
        dd, 0, DATEADD (
         year , +5 , getDate() 
        ) 
       ) 
     ) 
) 
    select * from Hours 
---------------------------- 
select * from vw_hoursalot option (maxrecursion 0) 
----------------------------* 
Các vấn đề liên quan