การเปรียบเทียบ SQLite DateTime


118

ดูเหมือนว่าฉันจะไม่ได้ผลลัพธ์ที่น่าเชื่อถือจากการสืบค้นเทียบกับฐานข้อมูล sqlite โดยใช้สตริงวันที่และเวลาเป็นตัวเปรียบเทียบ:

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

ฉันจะจัดการการเปรียบเทียบ datetime กับ sqlite ได้อย่างไร

update: field mydate เป็นประเภทข้อมูล DateTime


1
รูปแบบวันที่ใดที่เก็บค่าไว้ในmydateคอลัมน์ของคุณ ฉันเดาว่ามันไม่ใช่รูปแบบที่รองรับ SQLite: sqlite.org/lang_datefunc.html
OMG Ponies

1
OMG มันเป็นประเภทข้อมูลวันที่และเวลา
Brad

4
การใช้ datetime () นั้นจะทำให้ได้ค่าที่แน่นอนที่คุณให้มาไม่มีเหตุผลที่จะใช้ที่นี่เพียงแค่ใช้สตริงแทน และหากคุณจัดการกับวันที่เท่านั้นคุณควรลบส่วนที่เป็นศูนย์ - โดยพื้นฐานแล้วตรวจสอบให้แน่ใจว่าทั้งสองด้านอยู่ในรูปแบบเดียวกัน (มิฉะนั้น'2009-11-13'สำหรับ mydate จะน้อยกว่า'2009-11-13 00:00:00')

1
เพื่อให้ Visual Studio ที่มี SQLite ทำงานให้ฉันเรียกใช้แบบสอบถามวันที่ / เวลาฉันต้องใช้Datetime()เช่นเดียวกับที่ @Brad ได้รวมไว้ในการกล่าวถึงโซลูชันของเขา ไม่งั้น VS2012 บ่น ขอบคุณแบรด.
CaptainBli

ขอบคุณสำหรับการอัปเดตด้วยโซลูชัน แปลกแค่ไหนที่รูปแบบเริ่มต้นสำหรับวันที่ใน. NET จะส่งผลตรงกันข้ามสำหรับ "<" vs ">"
Dave Friedel

คำตอบ:


58

SQLite ไม่มีประเภทวันที่และเวลาโดยเฉพาะแต่มีฟังก์ชันวันที่เวลาวันที่และอย่าง ทำตามรูปแบบการแสดงสตริง (จริงๆแล้วมีเพียงรูปแบบ 1-10 เท่านั้น) ที่เข้าใจโดยฟังก์ชันเหล่านั้น (จัดเก็บค่าเป็นสตริง) จากนั้นคุณสามารถใช้งานได้รวมทั้งการเปรียบเทียบพจนานุกรมในสตริงจะตรงกับการเปรียบเทียบวันที่และเวลา (ตราบใดที่คุณไม่ทำ ลองเปรียบเทียบวันที่กับเวลาหรือเวลากับเวลาซึ่งไม่สมเหตุสมผลเลย)

ทั้งนี้ขึ้นอยู่กับภาษาที่คุณใช้คุณยังสามารถได้รับการแปลงโดยอัตโนมัติ (ซึ่งใช้ไม่ได้กับการเปรียบเทียบในคำสั่ง SQL เหมือนตัวอย่าง แต่จะทำให้ชีวิตของคุณง่ายขึ้น)


10
สำหรับทุกคนที่อ่านประโยคแรกใน '17 SQLite มีdateและdatetime
alisianoi

3
เมื่อวานอ่านเกี่ยวกับประเภทความสัมพันธ์ที่นี่: sqlite.org/datatype3.htmlโดยทั่วไปหากคุณต้องการวันที่คุณจะประกาศdate(หรือdatetime) ในคอลัมน์ซึ่งถือว่าเป็นการtextภายใน ที่เหมาะกับความต้องการของฉัน
alisianoi

100

YYYYMMDDเพื่อแก้ปัญหานี้ผมเก็บวันที่เป็น ดังนั้น where mydate >= '20090101' and mydate <= '20050505'

มันเป็นเพียงแค่การทำงานตลอดเวลา คุณอาจต้องเขียนโปรแกรมแยกวิเคราะห์เพื่อจัดการว่าผู้ใช้จะป้อนวันที่ของตนอย่างไรจึงจะสามารถแปลงเป็นYYYYMMDDได้


2
หากรูปแบบเป็นมาตรฐานการมี YYYY-MM-DD จะแตกต่างจากการไม่มีขีดกลางอย่างไร การเปรียบเทียบจะไม่จบลงเหมือนกัน?
Damon

2
@Damon: ฉันคิดว่าเขาใช้ int สำหรับประเภทข้อมูล
thumbmunkeys

1
ไม่นี่เป็นสตริง - คุณสามารถดูได้ที่เครื่องหมายคำพูด - แต่นี่เป็นแนวคิดที่ดี: ด้วยคำสั่งนี้YY MM DDคุณสามารถเปรียบเทียบวันที่ได้ @Damon มันควรใช้กับขีดกลางด้วย!
Sedat Kilinc

1
ฉันสงสัยว่าฉันสามารถทำสิ่งเดียวกันได้หรือไม่ถ้าฉันใช้รูปแบบ yyyyMMddHHmmss ในการจัดเก็บเพื่อที่ฉันจะได้รวมส่วนเวลาด้วย มันจะทำให้ล้นหรืออะไร?
faizal

2
ฉันใช้: yyyyMMddHHmm ไม่มีปัญหาฉันคาดว่า yyyyMMddHHmmss จะทำงานเหมือนเดิม
Steve Byrne

39

ฉันมีปัญหาเดียวกันเมื่อไม่นานมานี้และฉันแก้ไขได้ดังนี้:

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

% s ต้องอยู่ระหว่างอักขระ
เครื่องหมาย

มันได้ผล. โซลูชันที่แก้ไขเพื่อเลือกแถวทั้งหมดหลังจากวันที่กำหนด: SELECT * FROM table WHERE strftime ('% s', added)> strftime ('% s', "2017-01-01 00:00:00")
New Progammer

ฉันกำลังประเมินโดยใช้strftimeคำสั่ง WHERE ในตัวอย่างนี้และฉันมีคำถาม: การใช้strftimeแบบนี้มีประสิทธิภาพหรือไม่? มีการประเมินหนึ่งครั้งสำหรับทุกแถวหรือหนึ่งครั้งต่อแบบสอบถาม?
Alvaro Gutierrez Perez

ควรยอมรับว่าเป็นคำตอบที่ถูกต้อง!
Luka Sh

20

สิ่งต่อไปนี้ใช้งานได้ดีสำหรับฉันโดยใช้ SQLite:

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

สิ่งนี้ใช้ได้ผลสำหรับฉันใน iOS Objective-C My Query มีดังนี้: SELECT COUNT (carSold) FROM cars_sales_tbl WHERE date BETWEEN '2015-04-01' AND '2015-04-30' AND carType = "Hybrid"
Randika Vishman

9

Sqlite ไม่สามารถเปรียบเทียบกับวันที่ได้ เราต้องแปลงเป็นวินาทีและโยนเป็นจำนวนเต็ม

ตัวอย่าง

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


6

ฉันมีสถานการณ์ที่ฉันต้องการข้อมูลตั้งแต่สองวันที่แล้วจนถึงสิ้นวันนี้ ฉันมาถึงสิ่งต่อไปนี้

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

โอเคในทางเทคนิคฉันดึงเวลาเที่ยงคืนของวันพรุ่งนี้เหมือนโปสเตอร์ต้นฉบับถ้ามีข้อมูลใด ๆ แต่ข้อมูลของฉันเป็นข้อมูลในอดีตทั้งหมด

สิ่งสำคัญที่ต้องจำไว้คือผู้โพสต์เริ่มต้นจะไม่รวมข้อมูลทั้งหมดหลังจาก 2009-11-15 00:00:00 น. ดังนั้นข้อมูลใด ๆ ที่บันทึกไว้ตอนเที่ยงคืนของวันที่ 15 จะถูกรวมไว้แต่ข้อมูลใด ๆหลังเที่ยงคืนของวันที่ 15 จะไม่ถูกรวม หากคำถามของพวกเขาคือ

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

ใช้ระหว่างประโยคเพื่อความชัดเจน

มันจะดีขึ้นเล็กน้อย ยังไม่คำนึงถึงวินาทีอธิกสุรทินซึ่งหนึ่งชั่วโมงสามารถมีได้มากกว่า 60 วินาที แต่ก็ดีพอสำหรับการสนทนาที่นี่ :)


2

ฉันต้องจัดเก็บเวลาด้วยข้อมูลโซนเวลาในนั้นและสามารถรับคำค้นหาที่ทำงานในรูปแบบต่อไปนี้:

"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')"

เวลาจะถูกเก็บไว้ในฐานข้อมูลเป็น TEXT ปกติในรูปแบบต่อไปนี้:

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

2

ด้านล่างนี้เป็นวิธีเปรียบเทียบวันที่ แต่ก่อนหน้านั้นเราจำเป็นต้องระบุรูปแบบของวันที่ที่เก็บไว้ใน DB

ฉันมีวันที่เก็บไว้ในรูปแบบ MM / DD / YYYY HH: MM ดังนั้นจึงต้องเปรียบเทียบในรูปแบบนั้น

  1. แบบสอบถามด้านล่างเปรียบเทียบการแปลงวันที่เป็นรูปแบบ MM / DD / YYY และรับข้อมูลจากห้าวันที่ผ่านมาจนถึงวันนี้ ระหว่างตัวดำเนินการจะช่วยและคุณสามารถระบุวันที่เริ่มต้นและวันที่สิ้นสุดได้

    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. ข้อความค้นหาด้านล่างจะใช้ตัวดำเนินการมากกว่า (>)

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

การคำนวณทั้งหมดที่ฉันทำคือการใช้เวลาปัจจุบันคุณสามารถเปลี่ยนรูปแบบและวันที่ได้ตามที่คุณต้องการ

หวังว่านี่จะช่วยคุณได้

Summved


1

คุณยังสามารถเขียนฟังก์ชันผู้ใช้ของคุณเองเพื่อจัดการวันที่ในรูปแบบที่คุณเลือก SQLite มีวิธีการที่ค่อนข้างง่ายสำหรับการเขียนฟังก์ชันผู้ใช้ของคุณเอง ตัวอย่างเช่นฉันเขียนบางส่วนเพื่อเพิ่มระยะเวลาเข้าด้วยกัน


0

คำถามของฉันฉันทำดังนี้:

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

ฉันได้รับคำแนะนำจากคำตอบของ @ ifredy ทั้งหมดที่ฉันทำคือฉันต้องการให้คิวรีนี้ทำงานใน iOS โดยใช้ Objective-C และได้ผล!

หวังว่าคนที่พัฒนา iOS จะได้รับประโยชน์จากคำตอบนี้ด้วย!


0

ตอนนี้ฉันกำลังพัฒนาโดยใช้แพ็คเกจ System.Data.SQlite NuGet (เวอร์ชัน 1.0.109.2) ซึ่งใช้ SQLite เวอร์ชัน 3.24.0.

และสิ่งนี้ใช้ได้กับฉัน

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

ฉันไม่ได้ใช้ฟังก์ชัน datetime () บางทีพวกเขาได้อัปเดตแบบสอบถาม SQL ในเวอร์ชัน SQLite นั้นแล้ว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.