SQLite date compare - sqlite

How do I compare dates in SQLite database which are stored in DD-MMM-YYYY format e.g. 10-OCT-2017?
I want to compare dates and select rows of particular date and adjacent dates.

Short answer:
Painfully. You must convert the datestring, particularly the character month, into a numeric value, then you can compare the date values.
... Or more easily, by storing your dates using a format like “2018-01-01” which can be natively compared within the SQL via SQLite date functions.
Longer Answer
This page shows all the SQLite SQL date-time functions available. None of them produce or manipulate character month values. So your options are:
1) Select a group of records via SQL into a dataset; and then use your programming language to convert the date values in the dataset to a format whose values are comparable; then compare them.
This would have poor performance for anything except very small data queries, but would probably be reasonably simple to implement, and have no data conversion necessary. (To specifically answer the question you asked, this is the best solution for an app selecting few and small datasets.)
2) Create a SQLite function to do the date format conversion. To do that, you use SQLite's C API. See more how-to discussion here.
I haven't done this myself, and I wouldn’t recommend this route just due to the learning curve, but also due to the type & purpose of SQLite and its capabilities. (To specifically answer the question you asked, this is the best solution for not few and not small datasets.)
3) (This option does not answer your specific question) Convert your stored date values to a natively SQL comparable format. Like: “2018-01-01”. Then you can use the SQLite date-time functions for adjacent date comparisons.
Sample:
select mySQLTableDate, myOtherSQLTableDate
date(mySQLTableDate,'+1 day'), -- YYYY-DD-MM stored format
date(strftime('%Y-%m-%d', mySQLTableDate),'+1 day') -- many stored formats
from mySQLTable
where select mySQLTableDate = date(myOtherSQLTableDate,'+1 day')
Answering your question in terms of the goal rather than the specific question :) , my recommendation is to Use This Solution, especially if you are scanning a lot of data. See more about SQLite Date types here, but for dates with no time, I just store them as the string “2018-01-01”. I’m working with .js, and this is very simple to convert to/from a .js Date object.

Related

Writing date and time into SQL database in R

I am trying to create a SQL database using a data set with a column that has both date and time included in it. The problem that I am running into is when the data is written into a SQL database, and read back into R the date and time column end up having a numeric structure rather than a Posixct structure or does not show the date and times correctly.
I have been using the RSQlite and DBI package to work between the two. I just started working with SQL, is there an appropriate way in reading date and time columns into a SQL database?
Thank you for your time.
SQLite does not support date and time types. Here are some options:
convert the date/time fields back to R classes yourself. You could write a separate function for each table read into R that reads in the table and does the conversion transparently or you could adopt a naming convention for the columns that lets a single function perform the conversion according to the naming rules if you control the database itself. Another way to implement a naming convention, other than writing your own function, is to use the sqldf package. If you use sqldf("select ...", dbname = "mydb", connection = con, method = "name__class") it will convert every column whose name has two underscores to the class name after the two underscores. Note that name__class has two underscores as well.
the dbmisc package (also see this) can perform conversions. You must prepare a schema, i.e. layout specification, for each table, as described there, in order to use it.
Use a different database that does support date/time types. I usually use the H2 database in such cases. The RH2 package includes the entire H2 database software right in the R driver package in a similar manner to RSQLite.
As per a comment below, the latest version of RSQLite has support for time and date fields; however, note that that that is on the R side, like the other solutions above (except using H2), and does not change the fact that SQLite itself has no such support so, for example, if you use SQL to modify such a field such as adding 1 to get the next date it will no longer be of the same type.

How to handle null timestamps using coalesce in Teradata

I have three columns with datatype TIMESTAMP(6) and I wish to find out the minimum of the three timestamps. At any given time, there will be at least 1 non-null data point among the three columns.
I tried finding an alternative online but couldn't find anything related to timestamp comparison on this matter. There is a solution of using coalesce which works on data type date but not on timestamps.
I'm guessing you are asking about trying to use LEAST with timestamps? I don't know why Teradata hasn't done anything about that. For timestamps, I just cast them as varchar. Nulls make it uglier, because you have to coalesce them with something, depending on if you want null to be less than everything else or not.
select
least (
coalesce(null,'9999-12-31'), --if you want nulls to not be the least
cast(current_timestamp as varchar(32)),
cast(timestamp '2018-01-01 05:00:00' as varchar(32)))
In a real query, you'll end up combining coalesce and cast for every column you want to feed into the least function.
EDIT:
I should probably add that this works on YYYY-MM-DD dates, other formats may not sort correctly.

Range query on Date value in DocumentDB

According to this article, it's best to convert Date into Epoch time in order to use it is range query in DocumentDB. However, as recently the range query on Sting values has been added to DocumentDB, it is necessary to do convert date-time to epoch (as long as all date-time values have the same format and are in UTC format)?
This is similar to this question, where the accepted answer suggests using strings as you point out.
But to answer your question more specifically, DocumentDB cannot store JavaScript Date objects because it only stores pure JSON and Date is not a part of the JSON spec. So, you (or your client API) needs to do something with Date objects. By default, the node.js and .NET clients will convert Date objects to ISO-8601 formatted strings so using strings is actually a bit easier than Epoch. Just send the Date object to the database. The one trick to keep in mind here is that it's not converted back into a Date object when you read it. It comes back as a string. You have to do the conversion yourself. In JavaScript, this is easy. Just call new Date(yourDateString). Not sure about .NET or the other platforms.

Issue regarding epoch in SQLite

I've done a web application using PHP and postgres. Now, that same application I'm translating to JavaScript and SQLite. I must say, it's not been too tough and SQLite has successfully been able to interpret the same queries as I use in postgres.
Except for this one.
SELECT SUM(t.subtotal)/MAX(EXTRACT(epoch FROM (r.fecha_out - r.fecha_in))/86400) AS subtotal,
COUNT(t.id) AS habitaciones FROM reserva_habitacion t
LEFT JOIN reserva r ON t.id_reserva=r.id
WHERE (r.fecha_in <= "2015-03-27" AND r.fecha_out > "2015-03-27") AND r.estado <> 5
Using the FireFox plugin "SQLiteManager" it hints me that the error is this part epoch FROM, but I cannot get my head around it. What am I doing wrong and how could I fix it?
Any suggestions are welcome!
SQLite, unusually for a relational database, is completely dynamically typed, as discussed in this manual page.
Postgres, in contrast, is strictly typed, and uses operator overloading so that timestamp - timestamp gives you an interval. An interval can then be passed to the SQL-standard extract() function, in this case to give a total number of seconds between two timestamps. (See the manual page on Date/Time functions and operators.)
In SQLite, you have no such column type, so you have two choices:
Store your DateTimes as Unix timestamps directly; at this point, the extract epoch from is redundant, because r.fecha_out - r.fecha_in will give you the difference in seconds.
Store your DateTimes as strings in a standard format, and use the SQLite Date and Time functions to work with them. In this case, you could use strftime('%s', foo) to convert each value to a Unix timestamp, e.g. strftime('%s', r.fecha_out) - strftime('%s', r.fecha_in)

Sqlite dd/mm/yyyy format. How to avoid conversion?

The program I am currently designing use the dd/mm/yyyy date format, while Sqlite standard format is yyyy-mm-dd. My program make use of quite a lot of date calculations using julianday('yyyy-mm-dd'). I know I could convert the dd/mm/yyyy format to yyyy-mm-dd by using SUBSTR(X,Y) manipulation or by using the code of the language I am designing the db front-end; but i wish to avoid those. Any Idea?
You should always store dates (and timestamps) using native date format that is provided by database engine for following reasons:
Native formats permit native date arithmetic functions to work.
Native formats permit indexes to be consistently applicable, so you can use date comparisons efficiently and use operators like BETWEEN.
Native formats take less space to store on disk. For SQLite, storing date as real number of days from 4174 BC or as integer number of seconds since Jan 1st, 1970 takes 8 bytes. For your representation, it will take at least 10 bytes.
While SQLite does not really have true native date/datetime type (which is big omission in my opinion), it does have 3 permissible formats: TEXT, REAL or INTEGER that are still treated (to some extent) as native datetime formats, and all advantages outlined above still apply.
When you need to display dates in your application, you should use libraries provided by your scripting or other programming languages that know how to display dates in desired format.
In other words, use database to store, compare and retrieve data, and use your application to render it in desired format.

Resources