2009-10-27 33 views
78

Trong SQL Server 2000 và 2005:SQL: GIỮA vs <= and > =

  • sự khác biệt giữa hai WHERE mệnh đề này là gì?
  • cái nào tôi nên sử dụng trên trường hợp nào?

Query 1:

SELECT EventId, EventName 
FROM EventMaster 
WHERE EventDate BETWEEN '10/15/2009' AND '10/18/2009' 

Query 2:

SELECT EventId, EventName 
FROM EventMaster 
WHERE EventDate >='10/15/2009' 
    AND EventDate <='10/18/2009' 

(Edit: các EVENTDATE thứ hai ban đầu thiếu, vì vậy truy vấn là cú pháp sai)

+1

Đây là một bản sao hoàn toàn trùng lặp với http://stackoverflow.com/questions/1572840/sql-between-v1-and-v2 – mjv

+4

không thực sự, việc xử lý datetime hơi khác một chút, cộng với SQL Server 2008, và không có cách nào Shyju có thể chắc chắn mà không hỏi rằng câu trả lời sẽ giống nhau cho các phiên bản trước. – Irfy

Trả lời

82

Chúng giống nhau: BETWEEN là một cách viết tắt cho cú pháp dài hơn trong câu hỏi.

Sử dụng cú pháp dài hơn thay thế nơi BETWEEN không hoạt động, ví dụ:

Select EventId,EventName from EventMaster 
where EventDate >= '10/15/2009' and EventDate < '10/18/2009' 

(Lưu ý < hơn <= trong điều kiện thứ hai.)

+14

Có thể bạn nên nhấn mạnh rằng điều kiện thứ hai là '<'.Nó đã cho tôi một thời gian để phát hiện sự khác biệt. – zendar

+16

Tôi sẽ thêm rằng tôi đặc biệt khuyên bạn không bao giờ sử dụng GIỮA trừ khi bạn đang xử lý loại dữ liệu DATE hoặc đã bảo đảm rằng các giá trị ngày giờ của bạn sẽ không bao giờ có thành phần thời gian. Việc nhất quán về điều này sẽ khiến bạn ít có khả năng sử dụng BETWEEN do nhầm lẫn thay vì> = và

+1

Sẽ có bước trình biên dịch thứ hai như GIỮA được chuyển đổi thành điều kiện? Tôi hiểu điều này là một chút nhỏ nhưng sẽ có một chi phí bổ sung? –

4

Thông thường, không có sự khác biệt - từ khóa BETWEEN không được hỗ trợ trên tất cả các nền tảng RDBMS, nhưng nếu nó là, hai truy vấn nên giống hệt nhau.

Vì chúng giống hệt nhau, thực sự không có sự phân biệt về mặt tốc độ hay bất kỳ thứ gì khác - hãy sử dụng cái có vẻ tự nhiên hơn với bạn.

3

Tôi nghĩ sự khác biệt duy nhất là số lượng đường cú pháp trên mỗi truy vấn. GIỮA GIỮA chỉ là một cách khéo léo để nói chính xác giống như truy vấn thứ hai.

Có thể có một số khác biệt cụ thể của RDBMS mà tôi không biết, nhưng tôi không thực sự nghĩ như vậy.

28

Chúng giống nhau.

Một điều cần phải cẩn thận của, là nếu bạn đang sử dụng này để chống lại một DATETIME, phù hợp cho ngày kết thúc sẽ là sự khởi đầu trong ngày:

<= 20/10/2009 

là không giống nhau như:

<= 20/10/2009 23:59:59 

(nó sẽ trận đấu với <= 20/10/2009 00:00:00.000)

+0

Bạn chỉ có thể sử dụng giữa '2009-10-20' và '2009-10-21' trong trường hợp đó để chụp ngày –

+3

@DavidAndreiNed cũng sẽ khớp với '2009-10-21 00: 00: 00.000' - có thể không phải là những gì bạn muốn. –

2

logic không có sự khác biệt ở tất cả. Hiệu suất-khôn ngoan có -typically, trên hầu hết các DBMSes-không có sự khác biệt ở tất cả.

4

Như đã đề cập bởi @marc_s, @Cloud, et al. về cơ bản chúng giống nhau cho một phạm vi khép kín.

Nhưng bất kỳ giá trị thời gian phân đoạn có thể gây ra vấn đề với một loạt đóng (-bình đẳng lớn hơn-hay và ít-or-bằng) như trái ngược với một loạt half-open (lớn-hoặc-bình đẳng và ít hơn) với giá trị kết thúc sau khoảnh khắc cuối cùng có thể.

Vì vậy, để tránh điều đó truy vấn nên được viết lại như sau:

SELECT EventId, EventName 
    FROM EventMaster 
WHERE (EventDate >= '2009-10-15' AND 
     EventDate < '2009-10-19') /* <<<== 19th, not 18th */ 

Kể từ BETWEEN không làm việc cho khoảng nửa mở Tôi luôn luôn có một cái nhìn cứng tại bất kỳ truy vấn ngày/giờ sử dụng nó, vì nó có thể là một lỗi.

2

Xem điều này excellent blog post từ Aaron Bertrand về lý do bạn nên thay đổi định dạng chuỗi và cách xử lý các giá trị biên trong truy vấn phạm vi ngày.

2

Tôi có một sở thích nhỏ cho BETWEEN bởi vì nó làm cho nó ngay lập tức rõ ràng cho người đọc rằng bạn đang kiểm tra một trường cho một phạm vi. Điều này đặc biệt đúng nếu bạn có tên trường tương tự trong bảng của bạn.

Nếu, nói, bảng của chúng tôi có cả một transactiondatetransitiondate, nếu tôi đọc

transactiondate between ... 

Tôi biết ngay rằng cả hai đầu của thử nghiệm là đối với một lĩnh vực này.

Nếu tôi đọc

transactiondate>='2009-04-17' and transactiondate<='2009-04-22' 

tôi phải mất một ít thời gian để đảm bảo rằng hai lĩnh vực đều giống nhau.

Ngoài ra, khi truy vấn được chỉnh sửa theo thời gian, một lập trình viên cẩu thả có thể tách riêng hai trường. Tôi đã nhìn thấy rất nhiều truy vấn mà nói điều gì đó như

where transactiondate>='2009-04-17' 
    and salestype='A' 
    and customernumber=customer.idnumber 
    and transactiondate<='2009-04-22' 

Nếu họ thử điều này với một BETWEEN, tất nhiên, nó sẽ là một lỗi cú pháp và kịp thời sửa chữa.

11

Mặc dù BETWEEN dễ đọc và bảo trì, tôi hiếm khi khuyên bạn nên sử dụng vì nó là khoảng thời gian đóng và như đã đề cập trước đây có thể là vấn đề với ngày - thậm chí không có thành phần thời gian. Ví dụ, khi xử lý dữ liệu hàng tháng, thường là so sánh ngày BETWEEN first AND last, nhưng trong thực tế, việc viết dt >= first AND dt < next-first cũng dễ dàng hơn (cũng giải quyết được vấn đề về thời gian) - vì việc xác định last thường dài hơn một bước xác định next-first (bằng cách trừ đi một ngày).

Ngoài ra, một dấu hiệu khác là giới hạn dưới và trên cần phải được chỉ định trong đúng thứ tự (ví dụ: BETWEEN low AND high).

+0

@DavidAndreiNed Sai. Đừng lan truyền điều này. – Atys

Các vấn đề liên quan