2011-11-18 53 views
50

Tôi đang chạy sqlite để chọn dữ liệu giữa hai phạm vi cho báo cáo bán hàng. Để chọn dữ liệu từ giữa hai ngày, tôi sử dụng tuyên bố sau:SQL Chọn giữa các ngày

SELECT * FROM test WHERE date BETWEEN "11/1/2011" AND "11/8/2011"; 

Tuyên bố này lấy tất cả các ngày ngay cả ngoài những tiêu chí. Định dạng ngày bạn thấy đã nhập có cùng định dạng mà tôi quay lại. Tôi không chắc chắn những gì sai nhưng đánh giá cao bất kỳ sự giúp đỡ tôi có thể tìm thấy. Cảm ơn!

+1

Chỉ cần một mẹo nhanh chóng liên quan. Nếu bạn luôn có thể sử dụng định dạng yyyy/MM/dd. Nó sẽ ngăn chặn các vấn đề khác biệt khu vực pesky có thể là vấn đề của bạn. – Haedrian

Trả lời

69

SQLLite yêu cầu ngày ở định dạng YYYY-MM-DD. Vì dữ liệu trong cơ sở dữ liệu của bạn và chuỗi trong truy vấn của bạn không có định dạng đó, nó có thể xử lý "ngày" của bạn dưới dạng chuỗi.

+0

Sau khi thay đổi định dạng ngày, tôi chạy truy vấn lần nữa là 'CHỌN ngày TỪ CHỌN NGÀY GIỮA GIỮA "2011-11-1" VÀ "2011-11-2";' và lấy lại kết quả cho 2011-11-16:/ – Zombian

+26

Đó là ngày mùng 10 và ngày 20 của tháng. Thử 'BETWEEN '2011-11-01' VÀ '2011-11-02''. –

+0

@LarryLustig couuld bạn cho tôi biết cách sửa lỗi của tôi, tôi có cùng sự cố với máy chủ sql 2014 –

25

Thay đổi dữ liệu của bạn thành định dạng đó để sử dụng sqlite datetime formats.

YYYY-MM-DD 
YYYY-MM-DD HH:MM 
YYYY-MM-DD HH:MM:SS 
YYYY-MM-DD HH:MM:SS.SSS 
YYYY-MM-DDTHH:MM 
YYYY-MM-DDTHH:MM:SS 
YYYY-MM-DDTHH:MM:SS.SSS 
HH:MM 
HH:MM:SS 
HH:MM:SS.SSS 
now 
DDDDDDDDDD 

SELECT * FROM test WHERE date BETWEEN '2011-01-11' AND '2011-08-11' 
+0

Ý tưởng đúng, nhưng cho rằng dữ liệu quay lại cũng có định dạng 'MM/DD/YYYY', tôi nghi ngờ rằng điều này vẫn không hoạt động vì dữ liệu trong cơ sở dữ liệu của anh ta sẽ được coi là chuỗi thay vì ngày tháng. –

+0

@EricPetroelje Có - nhưng một khi bạn kết hợp định dạng trong DB với định dạng trong truy vấn, nó sẽ hoạt động.Dường như nó đã được chỉnh sửa sau này để bao gồm những gì các truy vấn cập nhật nên được một khi DB được cập nhật - mặc dù truy vấn cần báo giá duy nhất thay vì dấu ngoặc kép. – vapcguy

9

Thêm một cách để chọn giữa ngày tháng trong SQLite là sử dụng mạnh mẽ strftime chức năng:

SELECT * FROM test WHERE strftime('%Y-%m-%d', date) BETWEEN "11-01-2011" AND "11-08-2011" 

Đây là tương đương theo https://sqlite.org/lang_datefunc.html:

date(...) 

strftime('%Y-%m-%d', ...) 

nhưng nếu bạn muốn có nhiều lựa chọn hơn, bạn có nó.

+0

Dấu ngoặc kép phải là dấu nháy đơn, nhưng nếu không truy vấn sẽ hoạt động. – vapcguy

4

Hoặc bạn có thể truyền chuỗi của mình sang định dạng Ngày với chức năng ngày. Ngay cả ngày được lưu trữ dưới dạng TEXT trong DB. Như thế này (biến thể hoàn toàn khả thi nhất):

SELECT * FROM test WHERE date(date) 
BETWEEN date('2011-01-11') AND date('2011-8-11') 
+0

Tôi nghĩ rằng vấn đề với giải pháp này là bạn không chỉ định định dạng ngày của TEXT (ví dụ: nếu chuỗi ngày được lưu trữ dưới dạng 'MM/DD/YYYY'). Tôi đã thử cách tiếp cận này và nó không hiệu quả với tôi, và tôi nghĩ đó là lý do. –

1
SELECT * 
FROM TableName 
WHERE julianday(substr(date,7)||'-'||substr(date,4,2)||'-'||substr(date,1,2)) BETWEEN julianday('2011-01-11') AND julianday('2011-08-11') 

Lưu ý rằng tôi sử dụng định dạng: dd/mm/yyyy

Nếu bạn sử dụng d/m/yyyy, Thay đổi trong substr()

Hy vọng điều này sẽ giúp bạn.

+0

Sử dụng tuyệt vời của nối! Đã bỏ phiếu. Lưu ý rằng bạn không cần sử dụng 'julianday()', và sử dụng giả sử ngày của bạn là UTC vì 'julianday()' tính theo thời gian dựa trên GMT, vì vậy bạn có thể kết thúc với ngày tháng mà bạn don không muốn, và bao gồm những ngày bạn làm, nếu ngày tháng của bạn là giờ địa phương. Bạn có thể chỉ cần thực hiện 'SELECT * FROM TableName WHERE substr (ngày, 7) || '-' || substr (ngày, 4,2) || '-' || substr (ngày, 1,2) GIỮA '2011-01-11' VÀ '2011-08-11'' và nó sẽ hoạt động. – vapcguy

+0

Đặc biệt cảm ơn [Jeff] (http://stackoverflow.com/users/781965/jeff) và [vapcguy] (http://stackoverflow.com/users/1181535/vapcguy) tương tác của bạn thực sự đáng khích lệ –

1

Cảm ơn đặc biệt tới Jeffvapcguy tương tác của bạn thực sự đáng khích lệ.

Đây là một tuyên bố phức tạp hơn đó là hữu ích khi chiều dài giữa '/' là chưa biết ::

SELECT * FROM tableName 
WHERE julianday(
    substr(substr(date, instr(date, '/')+1), instr(substr(date, instr(date, '/')+1), '/')+1) 
||'-'|| 
    case when length(
    substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1),'/')-1) 
    )=2 
    then 
    substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1) 
    else 
    '0'||substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1) 
    end 
||'-'|| 
    case when length(substr(date,1, instr(date, '/')-1)) =2 
    then substr(date,1, instr(date, '/')-1) 
    else 
    '0'||substr(date,1, instr(date, '/')-1) 
    end 
) BETWEEN julianday('2015-03-14') AND julianday('2015-03-16') 
+0

Cảm ơn bạn đã khen ngợi, và phải trao nó cho bạn để có khả năng làm các chất nền. Bình luận của tôi về 'julianday()' từ bài viết khác vẫn được áp dụng. Về cơ bản, câu trả lời này giống với câu trả lời khác trừ khi bạn đưa vào logic điều kiện để thêm vào các số 0 đứng đầu cho các ngày và tháng đơn lẻ. Có lẽ lẽ ra đã được thêm vào câu trả lời khác, hoặc thay thế bằng bản chỉnh sửa này. Upvoted, vì nó là chính xác hơn, mặc dù. – vapcguy

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