2009-12-29 34 views
86

tôi dường như không thể có được kết quả đáng tin cậy từ các truy vấn đối với một cơ sở dữ liệu SQLite sử dụng một chuỗi datetime như một sự so sánh như vậy:SQLite DateTime so

select * 
    from table_1 
where mydate >= '1/1/2009' and mydate <= '5/5/2009' 

làm thế nào tôi nên xử lý so sánh datetime để SQLite?

update: lĩnh vực mydate là một kiểu dữ liệu DateTime

Giải pháp:

sau chức năng datetime và có một định dạng chuỗi như YYYY-MM-DD HH: mm: ss i đạt được kết quả tốt như sau

select * 
    from table_1 
    where mydate >= Datetime('2009-11-13 00:00:00') 
    and mydate <= Datetime('2009-11-15 00:00:00') 
+1

Định dạng ngày nào là giá trị được lưu trữ trong cột 'mydate'? Tôi đoán nó không phải là một trong những định dạng được hỗ trợ SQLite: http://www.sqlite.org/lang_datefunc.html –

+0

OMG, đó là kiểu dữ liệu datetime – Brad

+2

Việc sử dụng datetime() đó sẽ dẫn đến giá trị chính xác mà bạn đã cung cấp , không có lý do gì để sử dụng nó ở đây: chỉ cần sử dụng chuỗi thay thế. Và nếu bạn chỉ xử lý các ngày, bạn nên xóa các phần thời gian bằng không --- về cơ bản đảm bảo cả hai bên đều có cùng định dạng. (Nếu không ''2009-11-13'', cho mydate, sẽ nhỏ hơn'' 2009-11-13 00: 00: 00''.) –

Trả lời

46

SQLite không có ngày giờ chuyên dụng types, nhưng không có few datetime functions. Thực hiện theo các định dạng chuỗi đại diện (thực sự chỉ định dạng 1-10) được hiểu bởi các hàm đó (lưu trữ giá trị dưới dạng chuỗi) và sau đó bạn có thể sử dụng chúng, cộng với so sánh từ điển trên các chuỗi sẽ khớp với so sánh datetime (miễn là bạn không cố gắng so sánh ngày với thời gian hoặc thời gian biểu với thời gian, mà không làm cho một toàn bộ rất nhiều ý nghĩa anyway).

Tùy thuộc vào ngôn ngữ bạn sử dụng, bạn thậm chí có thể nhận được automatic conversion. (Mà không áp dụng để so sánh trong các câu lệnh SQL như ví dụ, nhưng sẽ làm cho cuộc sống của bạn dễ dàng hơn.)

+1

Đối với tất cả những người đọc câu đầu tiên, trong '17 SQLite có 'ngày' và' datetime' – alisianoi

+0

@ all3fox Bất kỳ ý tưởng nào về cách sử dụng? Không thể tìm thấy tài liệu thích hợp. – dustblue

+0

Hôm qua đã đọc về loại mối quan hệ ở đây: https://www.sqlite.org/datatype3.html Về cơ bản, nếu bạn cần một ngày, bạn khai báo một 'date' (hoặc' datetime') trên cột mà nội bộ được coi là 'văn bản'. Điều đó phù hợp với nhu cầu của tôi. – alisianoi

85

Để giải quyết vấn đề này, tôi lưu trữ ngày là YYYYMMDD. Do đó, where mydate >= '20090101' and mydate <= '20050505'

Nó chỉ đơn giản HOẠT ĐỘNG mọi lúc. Bạn chỉ có thể cần phải viết một trình phân tích cú pháp để xử lý cách người dùng có thể nhập ngày của họ để bạn có thể chuyển đổi chúng thành YYYYMMDD.

+2

Cung cấp định dạng được chuẩn hóa, cách có YYYY-MM-DD khác với không có dấu gạch ngang? Sẽ không so sánh kết thúc như nhau? – Damon

+1

@ Damon: tôi nghĩ anh ấy sử dụng int cho datatype – thumbmunkeys

+1

Không, đây là những chuỗi - bạn có thể thấy nó ở dấu ngoặc kép - Nhưng đây là ý tưởng tuyệt vời: Với thứ tự này ** YY MM DD ** có thể so sánh ngày. @ Damon nó cũng nên làm việc với các dấu gạch ngang! –

1

Bạn cũng có thể viết your own user functions để xử lý các ngày theo định dạng bạn chọn. SQLite có một phương pháp khá đơn giản để viết các hàm người dùng của riêng bạn. Ví dụ, tôi đã viết một vài để thêm thời gian với nhau.

27

tôi đã cùng một vấn đề thời gian gần đây, và tôi giải quyết nó như thế này:

SELECT * FROM table WHERE 
    strftime('%s', date) BETWEEN strftime('%s', start_date) AND strftime('%s', end_date) 
+0

% s phải được đặt giữa các ký tự trích dẫn đơn lẻ, ví dụ: strftime ('% s', date) – mvladic

+0

Nó hoạt động. Giải pháp sửa đổi để chọn tất cả các hàng sau ngày nhất định: CHỌN * TỪ bảng WHERE strftime ('% s', được thêm vào)> strftime ('% s', "2017-01-01 00:00:00") –

+0

Tôi đánh giá bằng cách sử dụng 'strftime' trong mệnh đề WHERE như trong ví dụ này, và tôi có một câu hỏi: Có hiệu quả khi sử dụng' strftime' như thế này? Nó được đánh giá một lần cho mỗi hàng hoặc một lần cho mỗi truy vấn? –

17

Sau đây là làm việc tốt cho tôi sử dụng SQLite:

SELECT * 
    FROM ingresosgastos 
    WHERE fecharegistro BETWEEN "2010-01-01" AND "2013-01-01" 
+0

Tôi sẽ kiểm tra điều này cho iOS và sẽ cho bạn biết! Nó hoạt động trên bảng điều khiển SQL PHPLiteAdmin! https://code.google.com/p/phpliteadmin/downloads/detail?name=phpliteAdmin_v1-9-4-1.zip –

+0

Điều này làm việc cho tôi trong iOS, Mục tiêu-C Truy vấn của tôi như sau: CHỌN COUNT (ô tô) FROM cars_sales_tbl WHERE date GIỮA '2015-04-01' VÀ '2015-04-30' AND carType = "Hybrid" –

1

tôi phải lưu trữ các thời gian với thông tin múi giờ trong đó và có thể nhận các truy vấn hoạt động với định dạng sau:

"SELECT * FROM events WHERE datetime(date_added) BETWEEN 
     datetime('2015-03-06 20:11:00 -04:00') AND datetime('2015-03-06 20:13:00 -04:00')" 

T ime được lưu trữ trong cơ sở dữ liệu như văn bản thường xuyên theo định dạng sau:

2015-03-06 20:12:15 -04:00 
0

truy vấn của tôi tôi đã làm như sau:

SELECT COUNT(carSold) 
FROM cars_sales_tbl 
WHERE date 
BETWEEN '2015-04-01' AND '2015-04-30' 
AND carType = "Hybrid" 

tôi đã gợi ý bằng câu trả lời @ ifredy của. Tất cả những gì tôi đã làm là, tôi muốn truy vấn này được chạy trong iOS, sử dụng Objective-C. Và nó hoạt động!

Hy vọng ai đó phát triển iOS, cũng sẽ sử dụng câu trả lời này!

6

Sqlite không thể so sánh vào ngày tháng.chúng ta cần chuyển đổi thành giây và bỏ nó thành số nguyên.

Ví dụ

SELECT * FROM Table 
WHERE 
CAST(strftime('%s', date_field) AS integer) <=CAST(strftime('%s', '2015-01-01') AS integer) ; 
4

Sau đây làm việc cho tôi.

SELECT * 
FROM table_log 
WHERE DATE(start_time) <= '2017-01-09' AND DATE(start_time) >= '2016-12-21' 
2

Dưới đây là những phương pháp để so sánh ngày nhưng trước đó chúng ta cần phải xác định định dạng của ngày lưu trong DB

tôi có ngày được lưu trữ trong MM/DD/YYYY HH: MM vì vậy nó có được so sánh ở định dạng đó

  1. Dưới đây truy vấn so sánh chuyển đổi ngày thành định dạng MM/DD/YYY và nhận dữ liệu từ năm ngày trước đến hôm nay. Toán tử BETWEEN sẽ giúp bạn và bạn có thể chỉ định ngày bắt đầu VÀ ngày kết thúc.

    select * from myTable where myColumn BETWEEN strftime('%m/%d/%Y %H:%M', datetime('now','localtime'), '-5 day') AND strftime('%m/%d/%Y %H:%M',datetime('now','localtime')); 
    
  2. Truy vấn bên dưới sẽ sử dụng lớn hơn toán tử (>).

    select * from myTable where myColumn > strftime('%m/%d/%Y %H:%M', datetime('now','localtime'), '-5 day');

Tất cả các tính toán tôi đã làm là sử dụng thời gian hiện tại, bạn có thể thay đổi định dạng và ngày theo nhu cầu của bạn.

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

Summved

0

Tôi có một tình huống mà tôi muốn dữ liệu từ tối đến hai ngày trước và cho đến cuối ngày hôm nay. Tôi đến sau đây.

WHERE dateTimeRecorded between date('now', 'start of day','-2 days') 
          and date('now', 'start of day', '+1 day') 

Ok, về mặt kỹ thuật tôi cũng kéo vào nửa đêm ngày mai như các poster ban đầu, nếu có bất kỳ dữ liệu, nhưng dữ liệu của tôi là tất cả lịch sử.

Điều quan trọng cần nhớ, áp phích ban đầu đã loại trừ tất cả dữ liệu sau 2009-11-15 00:00:00. Vì vậy, bất kỳ dữ liệu nào được ghi lại vào nửa đêm ngày 15 đều là bao gồm nhưng mọi dữ liệu sau nửa đêm vào ngày 15 thì không. Nếu truy vấn của họ là,

select * 
    from table_1 
    where mydate between Datetime('2009-11-13 00:00:00') 
        and Datetime('2009-11-15 23:59:59') 

Bạn đồng ý giữa khoản cho rõ ràng.

Nó sẽ tốt hơn một chút. Nó vẫn không tính đến giây nhảy vọt trong đó một giờ thực sự có thể có hơn 60 giây, nhưng đủ tốt để thảo luận tại đây :)

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