Sqlite SELECT * for Last 30 days - sqlite

I have a SQLite DB with the following columns:
File, Date_created, Owner
How do I get the list of files created in the last 30 days?
I tried the following, but it didn't limit the result. The list came back with files created 2 years ago!
SELECT * FROM Table1 WHERE Date_created > (SELECT DATETIME('now', '-30 day'))
Also, not sure if it matters, but my Created_date column is in the following date format: dd/mm/yyyy hh:mm:ss

SQLite doesn't have a native datetime data type, so that comparison's going to be on text. If your records are in DD/MM/YYYY format, you'll end up with comparisons like "07/03/2020" > "2020-06-07" which make little sense.
If you opt to store your datetimes as text, you must use a format that's lexicographically orderable. A great standard format that exhibits this property (if every piece of data has the same timezone, anyway) is ISO 8601, e.g. 2020-07-07 15:04:14+0300 at the time of writing in my timezone. As an aside, even xkcd recommends ISO 8601.
If you opt to store your datetimes as numbers, you can store them as either UNIX time, or maybe, if you're feeling adventurous, as e.g. the number 20200707150414. Do remember neither of these numeric options store timezone information, if that's important to your application.
As an aside,
SELECT * FROM Table1 WHERE Date_created > DATETIME('now', '-30 day')
is enough :)

Something like this might be what you are looking for, it's something that's come up in my head, haven't tested it.
Basically you're going 30 days backwards by Date_created.
SELECT * FROM Table1
WHERE DATEDIFF(DAY, DATEADD(DAY, -30, GETDATE()), Date_created) > 0

Related

How can I convert timestamps to dates in SQLite?

How can I convert timestamps to dates in SQLite?
The following code only produces a Timestamp column and a Date columns with NULL values. The the SQL code needs to convert from a "08/28/2020 8:00" format.
SQL CODE:
'''Select Timestamp, strftime('%m-%d-%Y', Timestamp) as Date
FROM Room_Data'''
The SQLite documentation is pretty clear, but I can't seem to get the desired result.
The strftime is meant to format a date, rather than perform conversion.
In the meantime you could try something like that to gather the pieces:
SELECT Timestamp,
SUBSTR(c,7,4) || '-' || SUBSTR(Timestamp,1,2) || '-' || SUBSTR(Timestamp,4,2) as Date
FROM Room_Data
Since SQlite doesn't really have the concept of a date, unlike other DBMS, the best choice would be to convert your dates to integer, either as Unix timestamps or in string form (YYYY-MM-DD) but storing dates as integer like 20201010 would be acceptable too.
NB: be careful with names like Timestamp or Date, they are reserved keywords in many programming languages and DBMSes.
The original code won't work in Windows 10 for some reason. Trying this from a Linux distro (Kubuntu, in this case) seems to resolve the issue. In Windows, the date needs to be converted to a '2020-01-01' format to actually work.
SQLite is amazing, but not sure why functionality changes for Windows 10. Feel free to comment if you know more about the differences.

Query between dates in SQLITE

I'm trying to query what happened between today and yesterday. To example on the 17th of June 2016 it would look like:
SELECT * FROM Inspection_Log WHERE date_time BETWEEN '2016-6-16' AND '2016-6-17'
But these days are relative, and this won't work say tomorrow, or really every again. So I've encountered this page where tells me now to use DATE as it's just a polite wrapper around strftime.
But here is my current issue:
This query works:
>SELECT COUNT(*) FROM Inspection_Log WHERE date_time BETWEEN '2016-6-16' AND '2016-6-17'
535
But when I use date('yada', '+1 day')
>SELECT COUNT(*) FROM Inspection_LOG WHERE date_time BETWEEN '2016-6-16' AND DATE('2016-6-16','+1 day')
0
So I try with strftime
>SELECT COUNT(*) FROM Inspection_LOG WHERE date_time BETWEEN '2016-6-16' AND strftime('%Y-%M-%D','2016-6-16','+1 day')
0
So I try with datetime
>SELECT COUNT(*) FROM Inspection_LOG WHERE date_time BETWEEN '2016-6-16' AND datetime('2016-6-16','+1 day')
0
Digging into this here is what i see
SELECT time('now')
'2016-06-24'
SELECT date('now')
'2016-06-24'
SELECT date('now','-1 day')
'2016-06-23'
SELECT date('2016-6-24','-1 day')
NONE
What am I doing wrong?
You need to change: AND strftime('%Y-%M-%D','2016-6-16','+1 day') for AND strftime('%Y-%m-%d','2016-06-16','+1 day').
1 - You should use '%Y-%m-%d' for the first parameter 'YYYY-MM-DD'.
The format string supports the most common substitutions found in the strftime() function from the standard C library plus two new substitutions, %f and %J. The complete list link
2 - A time string must be follow the format: YYYY-MM-DD, then you need to use '2016-06-16'.
There is a question and answer : SQL Select between dates
Okay so I was totally and completely wrong.
My scheme looks like this:
CREATE TABLE InspectionLog(
date_time DATE,
station_name TEXT,
inspection TEXT,
barcode_part_number TEXT,
bus_part_number TEXT,
barcode_serial_number TEXT,
bus_serial_number TEXT,
rework_operation TEXT,
status TEXT,
ng_description TEXT
)
DATE is not a valid data type. It is actually a high level wrapper around INTEGER and TEXT depending on the data placed into it. Sqlite3 defaults to TEXT.
What this means is when I perform an insert/update which does something similar to:
date_time = '2016-6-16'
This is valid as date_time is really TEXT not DATE. And when I preform a search that uses the DATE data type, it will skip any row which isn't a DATE.
The long version is. I inserted ~250MB incorrectly formatted into this table. After fixing my tests and functions so my inserts always have 2 day/month digits the majority of the OP's time queries work correctly.

What format is the Safari History.db history_visits.visit_time in?

When looking at the History.db from Safari, there's a table named history_visits which has a column named visit_time, which is a REAL value. It has values such as 470799793.096987. What format is that in? I'd like to see it in a format such as 12/08/2015 05:12:05.
It's the number in seconds since 00:00:00 UTC on 1 January 2001. It must be coming from an NSDate.
NSDate objects encapsulate a single point in time, independent of any particular calendrical system or time zone. Date objects are immutable, representing an invariant time interval relative to an absolute reference date (00:00:00 UTC on 1 January 2001).
— NSDate Class Reference
To get a decent human value out of it, you must add 978307200 (the epoch for 2001-01-01 00:00:00).
This query should give you what you want:
.headers on
select datetime(v.visit_time + 978307200, 'unixepoch', 'localtime') as date, v.visit_time + 978307200 as epoch, v.visit_time, i.domain_expansion, i.url
from history_items i left join history_visits v on i.id = v.history_item
order by i.id desc
limit 100;
Example output:
date|epoch|visit_time|domain_expansion|url
2015-12-31 11:51:27|1451562687.28465|473255487.284646|duckduckgo|https://duckduckgo.com/?q=current+timestamp+2015-12-31+11:51&t=osx
PS: Just for future reference, the Safari db file is located at ~/Library/Safari/History.db
To convert the visit_time value in the history.db in an excel spread sheet, open the history.db file in a tool such as DB browser for SQLLite (Windows) and export the history_visits values to a CSV file.
Open the CSV file and create a column where you will populate your values in human readable time adjusted to your time zone, and use the following formula convert your NSDate:
=((((C2+978307200)/60)/60)/24)+DATE(1970,1,1)+(-5/24)
In the above formula, the time value is in cell C2, and my time zone GMT-5. To adjust to your own time zone adjust the statement in the last set of parenthesis. Presently I have (-5/24) to represent GMT-5.
When I first approached this conversion, I mistakenly assumed the time in the history.db to be epoch time, which starts at 1/1/1970, and did not understand why there was such a skew in time. Adding the required conversion factor +978307200 solved the problem.
I found the domain_expansion field to be null in some cases, here's a modified query:
SELECT SUBSTR(
SUBSTR(url, INSTR(url, '/')+2),
1,
INSTR(SUBSTR(url, INSTR(url, '/')+2),'/') - 1
) domain,
url,
datetime(hv.visit_time + 978307200, 'unixepoch', 'localtime') visit_time
FROM history_items hi
JOIN history_visits hv on hi.id = hv.history_item;

Storing my dates as long (milliseconds) in SQLite: Can I use strftime(...)?

I'm storing my dates in SQLite in a column of data type INTEGER. I'm storing the milliseconds since 1970.
Eg:
date (long) other columns ...
-----------------------------------------
1407297600000 ...
1407211200000 ...
1407124800000 ...
My question is: how can I use strftime() under this circumstances?
If not, I should use TEXT as the column type??
Running this:
select strftime('%Y-%m', date) from my_table;
Is throwing nonesense stuff:
strftime('%Y-%m', date)
-----------------------------------------
1968-19
1968-19
1968-19
Unless you tell it otherwise, strftime() thinks those numbers are Julian day values - very different from Unix epoch milliseconds.
You'll want to convert to seconds, and tell strftime() these are Unix epoch numbers:
select strftime('%Y-%m', date / 1000, 'unixepoch');
See the Modifiers section in the SQLite Date and Time Functions docs.

I need a sqlite equivalent of the folling msaccess query

Select distinct Format(DateAdd(""s""," & columnname & ",""1/1/1980 12:00:00 AM""), 'dd-MMM-yyyy') as A
I have assumed that the seconds to add and the original date are hard coded values below whilst awaiting clarifications requested in the comments.
To add a number of seconds to a date you can use:
select datetime('1980-01-01 00:00:00', "345000 seconds");
This gives the result: 1980-01-04 23:50:00
The example above is just under 4 days in seconds, if you want to truncate the result to just the date as implied by the query in your questions then you can wrap this inside a date function. However, this would give the result in the format "YYYY-MM-DD" rather than "DD-MMM-YYYY" as your access query does.
Unfortunately I cannot find any native SQLite function to convert a numeric month value to mmm format. You can do this manually with replace (similar to the answer to this question), but this is a bit messy.
If you are happy to live with the numeric months then you can simply use:
select strftime('%d-%m-%Y', '1980-01-01 00:00:00', "345000 seconds");
This gives the result: 04-01-1980
More information on the SQLite date / time functions can be found here.

Resources