2015-04-30 15 views
6

Tôi sử dụng SQL server 2014, tôi thử truy vấn sau để chọn giữa hai ngày trong cùng một bảng, kiểu dữ liệu là nvarchar, tôi đã thực hiện truy vấn sau nó chỉ hiển thị cho tôi ba hàng như vậy ('30/03/2015','30/04/2015','30/04/2015'), nhưng trên thực tế có ('29/02/2015','30/03/2015','31/04/2015','30/04/2015','30/04/2015')Tại sao lựa chọn của tôi giữa hai ngày trong cùng một bảng không hoạt động?

select RegisteredDate 
from Student 
where Student.RegisteredDate between convert(nvarchar, '30/01/2014', 103) 
    and convert(nvarchar, '30/04/2015', 103) 
+0

thế nào là ngày định dạng trong bàn của bạn? –

+3

Đây là lý do tại sao bạn không bao giờ nên lưu trữ ngày là nvarchar. Bạn thực sự không cần phải cho phép các ký tự unicode ở đây chắc chắn. : S Khi bạn sử dụng các kiểu dữ liệu thích hợp, loại vấn đề này tự sửa lỗi. –

+1

@MarkKram ý của bạn là gì?datatype RegisteredDate là nvarchar –

Trả lời

2

Vì tôi đã đọc các câu trả lời và nhận xét khác, tôi có thể khuyên bạn trước hết nên thay đổi kiểu dữ liệu của "RegisteredDate" từ "nvarchar" thành "date". Thứ hai sử dụng tiêu chuẩn này 'yyyy-MM-dd' mã dưới đây là những gì bạn cần

select RegisteredDate 
from Student 
where Student.RegisteredDate between '2014-01-30' and '2015-04-30' 

bạn sẽ không cần bất kỳ chuyển đổi, đây là cách tôi làm điều đó cho bản thân mình

3

Cast theo chiều ngược lại, cách khác bạn đang so sánh chuỗi:

select RegisteredDate from Student 
where convert(date, Student.RegisteredDate, 103) between '20140130' and '20150430' 

thực tế là rằng những ngày lưu lại dưới dạng chuỗi được sắp xếp như sau:

'29/02/2015', 
'30/03/2015', 
'30/04/2015', 
'30/04/2015', 
'31/04/2015' 

Bây giờ hãy tưởng tượng bạn sẽ thêm giá trị bộ lọc vào đâu?

'29/02/2015', 

'30/01/2014' --start date 

/-------------\ 
|'30/03/2015',| 
|'30/04/2015',| 
|'30/04/2015',| 
\-------------/ 

'30/04/2015' --end date 

'31/04/2015' 

Vì vậy, between sẽ trả lại cho bạn ba hàng đó. Bạn cũng có trong dữ liệu của mình 29/02/2015. Trong 2015, tháng 2 sẽ kết thúc vào 28 (bạn đã có dữ liệu không chính xác trong bảng). Bạn sẽ không bao giờ có thể chèn các giá trị như vậy nếu bạn chọn các loại correctly.So kết luận là:

Sử dụng các kiểu dữ liệu thích hợp cho dữ liệu của bạn!

+1

nó mang lại cho tôi lỗi này Msg 241, Level 16, State 1, Line 1 chuyển đổi thất bại khi chuyển đổi ngày tháng và/hoặc thời gian từ chuỗi ký tự. –

+1

So sánh các chuỗi sẽ sử dụng thứ tự chữ cái char bằng char bắt đầu từ bên trái. Ví dụ: 20/01/1302 sẽ sau ngày 01/12/4016 khi "2" char đi sau "1" char. – borjab

+1

@Giorgi Nakeuri nhưng trong cơ sở dữ liệu không được tổ chức theo cách này (20150430) được tổ chức (30/04/2015) –

1

Cố gắng truyền chuỗi của bạn cho đến ngày thay vì truyền tất cả các ngày trong bảng thành chuỗi.

Bạn đang truyền tất cả các bản ghi trong bảng thành chuỗi và có thể là hàng triệu bản ghi. Bằng cách này không chỉ hiệu suất của bạn sẽ tốt hơn nhưng quan trọng hơn bạn sẽ so sánh chúng với ngày, không phải là String.

SELECT RegisteredDate 
    FROM Student 
WHERE Student.RegisteredDate BETWEEN Convert(Date, '30/01/2014',103) AND Convert(Date, '30/04/2015', 103) 

Như tôi đã nói trong phần nhận xét, so sánh chuỗi sử dụng thứ tự bảng chữ cái một char khác bắt đầu từ bên trái. Ví dụ: 20/01/1302 sẽ sau 01/12/4016 là "2" char theo sau ký tự "1" trong ASCII.

Cập nhật: chuyển đổi Student.RegisteredDate cho đến ngày nếu nó vẫn còn trong loại nvarchar. Tôi khuyên bạn nên thay đổi loại nếu bạn có thể làm điều này. Nó có thể là một nguồn của lỗi và các vấn đề hiệu suất nếu bạn không làm điều này.

SQL Server 2014 làm cho chuỗi ngày chuyển đổi tự động nhưng chỉ khi cần. So sánh chuỗi '30/04/2015 'với nvarchar chỉ là một so sánh String.

+0

Bạn vui lòng cho tôi biết (to_Date) là gì? –

+1

'30/01/2014 'chỉ là một loại Chuỗi như' Helloworld 'và' FooBar '. Chúng không có ý nghĩa về ngày tháng. Các loại ngày được tối ưu hóa cho cơ sở dữ liệu và thực hiện một số kiểm tra để bạn không tìm thấy '31/02/2015 'hoặc '33/13'1233'. To_date sẽ chỉ thay đổi kiểu Xem ví dụ: http://www.connectsql.com/2011/04/sql-server-basics-todate-function-in.html – borjab

+0

@borjab, isnt nó chỉ cho ORACL? –

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