So sánh DateTime trong SQLite


117

Tôi dường như không thể nhận được kết quả đáng tin cậy từ truy vấn dựa trên cơ sở dữ liệu sqlite bằng cách sử dụng chuỗi ngày giờ làm phép so sánh như vậy:

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

làm cách nào để xử lý so sánh ngày giờ với sqlite?

update: field mydate là kiểu dữ liệu DateTime


1
Định dạng ngày tháng mà giá trị được lưu trữ trong mydatecột của bạn là gì? Tôi đoán nó không phải là một trong những định dạng được hỗ trợ SQLite: sqlite.org/lang_datefunc.html
OMG Ngựa Non

1
Ôi trời, đó là kiểu dữ liệu datetime
Brad

4
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ý ngày tháng, bạn nên xóa phần không thời gian --- về cơ bản đảm bảo rằng cả hai bên đều ở cùng một định dạng. (Nếu không '2009-11-13', đối với mydate, sẽ ít hơn '2009-11-13 00:00:00'.)

1
Để Visual Studio với SQLite hoạt động với tôi để chạy truy vấn ngày / giờ, tôi cần sử dụng Datetime()như @Brad đã bao gồm trong đề cập của anh ấy về giải pháp. Nếu không thì VS2012 phàn nàn. Cảm ơn Brad.
CaptainBli

cảm ơn bạn đã cập nhật giải pháp của bạn. Thật kỳ lạ khi định dạng mặc định cho ngày tháng trong .NET thực sự sẽ dẫn đến điều ngược lại cho "<" vs ">".
Dave Friedel

Câu trả lời:


57

SQLite không có các loại ngày giờ chuyên dụng , nhưng có một vài hàm datetime . Thực hiện theo các định dạng biểu diễn chuỗi (thực tế 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ừ vựng trên các chuỗi sẽ khớp với so sánh ngày giờ (miễn là bạn không cố gắng so sánh ngày với thời gian hoặc ngày giờ với thời gian, dù sao điều này cũng không có ý nghĩa gì nhiều).

Tùy thuộc vào ngôn ngữ bạn sử dụng, bạn thậm chí có thể nhận được chuyển đổi tự động . (Điều này không áp dụng cho các phép so sánh trong các câu lệnh SQL như ví dụ, nhưng sẽ giúp cuộc sống của bạn dễ dàng hơn.)


10
Đối với tất cả những người đọc câu đầu tiên, trong '17 SQLite không có datedatetime
alisianoi

3
Hôm qua đã đọc về mối quan hệ kiểu ở đây: 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à text. Điều đó phù hợp với nhu cầu của tôi.
alisianoi

100

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

Nó chỉ hoạt động đơn giản mọi lúc. Bạn có thể chỉ cần 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 tháng của họ để bạn có thể chuyển đổi họ sang YYYYMMDD.


2
Với điều kiện định dạng được chuẩn hóa, việc có YYYY-MM-DD sẽ khác như thế nào so với việc không có dấu gạch ngang? Các so sánh sẽ không giống nhau sao?
Damon

2
@Damon: tôi nghĩ rằng ông sử dụng một int cho datatype
thumbmunkeys

1
Không, đây là các chuỗi - bạn có thể thấy nó ở phần trích dẫn - Nhưng đây là ý tưởng tuyệt vời: Với đơn đặt hàng YY MM DD này, bạn có thể so sánh các ngày. @Damon nó cũng sẽ hoạt động với dấu gạch ngang!
Sedat Kilinc

1
Tôi tự hỏi liệu tôi có thể làm điều tương tự không nếu tôi sử dụng định dạng yyyyMMddHHHmmss để lưu trữ, để tôi có thể bao gồm cả phần thời gian. Nó có gây ra tràn hay gì không?
faizal

2
Tôi sử dụng: yyyyMMddHHmm không có vấn đề gì, tôi mong đợi yyyyMMddHHmmss hoạt động như vậy
Steve Byrne

39

Tôi đã gặp vấn đề tương tự 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)

% s phải được đính kèm giữa các nhân vật dấu nháy đơn, ví dụ: strftime ( '% s', ngày)
mvladic

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: SELECT * FROM table WHERE strftime ('% s', đã thêm)> strftime ('% s', "2017-01-01 00:00:00")
mới

Tôi đang đánh giá việc sử dụng strftimetrong mệnh đề WHERE như trong ví dụ này và tôi có câu hỏi: Sử dụng strftimenhư thế này có hiệu quả không? Nó được đánh giá một lần cho mọi hàng hay một lần cho mỗi truy vấn?
Alvaro Gutierrez Perez

điều này nên được chấp nhận là câu trả lời chính xác!
Luka Sh

20

Điều sau đang hoạt động tốt đối với tôi khi sử dụng SQLite:

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

Điều này hoạt động đối với tôi trong iOS, Objective-C Truy vấn của tôi như sau: CHỌN COUNT (carSold) TỪ ô tô_sales_tbl TẠI ĐÂU ngày GIỮA '2015-04-01' VÀ '2015-04-30' VÀ carType = "Kết hợp"
Randika Vishman

9

Sqlite không thể so sánh ngày tháng. chúng ta cần chuyển đổi thành giây và ép kiểu số nguyên.

Thí dụ

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

8

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'

thay vào đó bạn có thể sử dụng giữa.
Tamim Attafi

6

Tôi gặp một tình huống mà tôi muốn có dữ liệu từ tối đa hai ngày trước và cho đến cuối ngày hôm nay. Tôi đến nơi 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 sẽ kéo vào nửa đêm ngày mai như người đăng ban đầu, nếu có bất kỳ dữ liệu nào, nhưng tất cả dữ liệu của tôi đều là lịch sử.

Điều quan trọng cần nhớ, người đăng ban đầu đã loại trừ tất cả dữ liệu sau ngày 11-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 được đưa vào nhưng bất kỳ dữ liệu nào sau nửa đêm 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')

Sử dụng mệnh đề between cho rõ ràng.

Nó sẽ tốt hơn một chút. Nó vẫn chưa tính đến giây nhuận trong đó một giờ thực sự có thể có hơn 60 giây, nhưng đủ tốt cho các cuộc thảo luận ở đây :)


2

Tôi phải lưu trữ thời gian với thông tin múi giờ trong đó và có thể nhận được 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')"

Thời gian được lưu trữ trong cơ sở dữ liệu dưới dạng TEXT thông thường ở định dạng sau:

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

2

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

Tôi có ngày được lưu trữ ở định dạng MM / DD / YYYY HH: MM nên nó phải được so sánh ở định dạng đó

  1. Truy vấn bên dưới so sánh chuyển đổi ngày thành định dạng MM / DD / YYY và lấy dữ liệu từ năm ngày qua cho đến hôm nay. Toán tử BETWEEN sẽ trợ giúp 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 toán tử lớn hơn (>).

      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 đã thực hiện đều sử dụng thời gian hiện tại, bạn có thể thay đổi định dạng và ngày tháng theo nhu cầu của mình.

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

Được tổng hợp


1

Bạn cũng có thể viết các hàm người dùng của riêng mình để xử lý ngày tháng ở đị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 số để thêm các khoảng thời gian với nhau.


0

Truy vấn của tôi, tôi đã thực hiện như sau:

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

Tôi nhận được gợi ý bởi câu trả lời của @ ifredy. 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 đó làm Phát triển iOS, cũng sẽ sử dụng được câu trả lời này!


0

Hiện tại, tôi đang phát triển bằng gói System.Data.SQlite NuGet (phiên bản 1.0.109.2). Mà sử dụng phiên bản SQLite 3.24.0.

Và điều này làm việc cho tôi.

SELECT * FROM tables WHERE datetime 
BETWEEN '2018-10-01 00:00:00' AND '2018-10-10 23:59:59';

Tôi không sử dụng hàm datetime (). Có lẽ họ đã cập nhật truy vấn SQL trên phiên bản SQLite đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.