I am developing android application. One of my application table has "foo_date" as column name. and data type is TEXT. I have following data in my table
primary key | foo_date | foo_value
--------------------------------------
1 2013-3-1 100
2 2013-3-2 2
3 2013-3-4 100
4 2013-3-3 1000
my requirement is to get data for the current week(i.e. 2013-3-4 to 2013-3-10). When i write below query, i am getting all data except row # 3
select * from foo_tbl where foo_date between '2013-3-4' and '2013-3-10';
How do I write sqlite query so that it includes all data for current week?
Thansk
Chintan
Your problem is that you have stored the dates in a format that cannot be compared easily; the character 1 comes before 4, so 2013-3-10 compares less than 2013-3-4.
As documented, you should use the ISO date format yyyy-mm-dd. With constant field sizes, you can use a query with string comparisons that work:
SELECT * FROM foo WHERE foo_date BETWEEN '2013-03-04' AND '2013-03-10'
or use a date function to compute the week:
SELECT * FROM foo WHERE strftime('%W', foo_date) = '09'
First, store the dates as standard sqlite time string format (i.e. YYYY-MM-DD).
Then, you can use this:
select * from foo where strftime('%W', foo_date) == strftime('%W', 'now')
to select the rows with the same week number as now.
Related
i am using DB Browser for SQLite and I'm new to this just now. I am looking for the timestamp type of attribute. Is real, timestamp in other words?
I have edited the type and also its default sirs. is this kind of right?
SQLite has a dyanmic/flexible type, which, with the exception of an alias of the rowid column (INTEGER PRIMARY KEY (with or without AUTOINCREMENT)) or the rowid column itself, allows any column to hold data of any storage type (TEXT, INTEGER, REAL, NULL or BLOB).
When a column is defined the column type resolves into one of 5 column types (column affinity) according to a set of rules (see link below),
e.g. even ..(mycolumn Rumplestilskin) is valid as it is resolved to a type affinity of NUMERIC* (rule 5 - see link below for rules). DECIMAL, DECIMAL(10,5) also drop down to rule 5 and thus result in a type affinity of **NUMERIC.
The above is an overview of Datatypes In SQLite Version 3
As such, except when considering the affect that type affinity has on the data when extracted, the column type isn't really a factor.
What is important is the actual data that you store.
In the case of dates/timestamps it will likely be best to store the data as one of the accepted Time Strings :-
A time string can be in any of the following formats:
YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM
HH:MM:SS
HH:MM:SS.SSS
now
DDDDDDDDDD
In formats 5 through 7, the "T" is a literal character separating the
date and the time, as required by ISO-8601.
Formats 8 through 10 that
specify only a time assume a date of 2000-01-01.
Format 11, the string
'now', is converted into the current date and time as obtained from
the xCurrentTime method of the sqlite3_vfs object in use. The 'now'
argument to date and time functions always returns exactly the same
value for multiple invocations within the same sqlite3_step() call.
Universal Coordinated Time (UTC) is used.
Format 12 is the Julian day
number expressed as a floating point value.
Formats 2 through 10 may be optionally followed by a timezone
indicator of the form "[+-]HH:MM" or just "Z". The date and time
functions use UTC or "zulu" time internally, and so the "Z" suffix is
a no-op. Any non-zero "HH:MM" suffix is subtracted from the indicated
date and time in order to compute zulu time. For example, all of the
following time strings are equivalent:
2013-10-07 08:23:19.120
2013-10-07T08:23:19.120Z
2013-10-07 04:23:19.120-04:00
2456572.84952685
In formats 4, 7, and 10, the fractional seconds value SS.SSS can have
one or more digits following the decimal point.
Exactly three digits are shown in the examples because only the first three digits are
significant to the result, but the input string can have fewer or more
than three digits and the date/time functions will still operate
correctly.
Similarly, format 12 is shown with 10 significant digits,
but the date/time functions will really accept as many or as few
digits as are necessary to represent the Julian day number.
Time Strings
The link immediately also includes the Date/Time Functions and examples of their use.
Consider the following :-
DROP TABLE IF EXISTS savetimestamps;
CREATE TABLE IF NOT EXISTS savetimestamps (
name TEXT,
ts01 rumplestiltskin DEFAULT CURRENT_TIMESTAMP,
ts02 INTEGER DEFAULT CURRENT_TIMESTAMP,
ts03 myreallybigintbutrealllyitisjustandint DEFAULT CURRENT_TIMESTAMP,
ts04 BLOB DEFAULT CURRENT_TIMESTAMP,
ts05 REAL DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO savetimestamps (name) VALUES('A');
INSERT INTO savetimestamps VALUES(1,'a',3.725,4,5,x'010203040506070809'); -- useless/confusing data
SELECT *,
rowid AS id,
STRFTIME('%d %M %Y', ts01) AS t1,
STRFTIME('%d %M %Y', ts02, '-1 DAYS') AS t2,
STRFTIME('%d %M %Y', ts03, '-2 DAYS') AS t3,
STRFTIME('%d %M %Y', ts04, '-3 DAYS') AS t4,
STRFTIME('%d %M %Y', ts05, '-4 DAYS') AS t5
FROM savetimestamps;
SELECT
name,typeof(ts01),typeof(ts02),typeof(ts03),typeof(ts04),typeof(ts05)
FROM savetimestamps;
This creates a table with 6 columns or varying column type affinities (TEXT, NUMERIC (rule 5) INTEGER, INTEGER (rule 1 as it contains int), BLOB and REAL).
The last 5 columns have a default value of the current timestamp, so not providing a value results in SQLite inserting the current timestamp.
2 rows are inserted the first row fitting the tables intended use i.e. a text value in the name column, and timestamps in the remaining 5. However, the 2nd row is garbage data for demonstration.
2 queries are then run the first displaying the stored data and also some columns using the strftime function to progressively show the previous day.
The second query displays the column types.
The results are :-
Notice the 2nd row how the column types differ within a column, thus each column/row has it's own specific type as per how the data was stored.
As an overview SQLite's data types are flexible but as a result can be confusing, especially if you come from a static data type background.
As timestamp is generally represented by a Long value, INTEGER is fine to store it inside a database.
I have a table with timestamp column and the values stored in timestamp column are like
20180608T002304.507Z , 20180608T001745.821Z, 20180608T001628.170Z, 20180608T001336.516Z
I would like to get timestamp in "YYYY-MM-dd" formate.
Used strftime() function , but no use
when I query strftime('%Y-%m-%d %H:%M', timestamp) getting null
Thanks in advance
This is not one of the supported time string formats. Change the values so that they contain the appropriate punctuation:
sqlite> SELECT date('20180608T002304.507Z');
sqlite> SELECT date('2018-06-08T00:23:04.507Z');
2018-06-08
Your issue is that strftime along with all the SQLite date functions require specific formats as listed below. 20180608T002304.507Z is not one of the formats, hence the null.
Note the following is based upon your query using strftime('%Y-%m-%d %H:%M', timestamp) as opposed to I would like to get timestamp in "YYYY-MM-dd" formate.
You have two options.
1. You could utilise the substr function e.g.
:-
substr(mytimestamp,1,4)||'-'||
substr(mytimestamp,5,2)||'-'||
substr(mytimestamp,7,2)||' ' ||
substr(mytimestamp,10,2)||':'||
substr(mytimestamp,12,2)
where mytimestamp is the column name
As an example, the following :-
DROP TABLE IF EXISTS mytable;
CREATE TABLE IF NOT EXISTS mytable (mytimestamp);
INSERT INTO mytable VALUES('20180608T002304.507Z'),('20180608T001745.821Z'),('20180608T001628.170Z'),('20180608T001336.516Z');
SELECT
substr(mytimestamp,1,4)||'-'||
substr(mytimestamp,5,2)||'-'||
substr(mytimestamp,7,2)||' ' ||
substr(mytimestamp,10,2)||':'||
substr(mytimestamp,12,2)
FROM mytable;
results in :-
2. Alter the source data to match one of the acceptable/recognised formats.
This could be done using something based upon :-
UPDATE mytable SET mytimestamp =
substr(mytimestamp,1,4)||'-'|| -- Year
substr(mytimestamp,5,2)||'-'|| -- Month
substr(mytimestamp,7,2)|| -- Day
substr(mytimestamp,9,1)|| -- T (or space)
substr(mytimestamp,10,2)||':'||
substr(mytimestamp,12,2)||':'||
substr(mytimestamp,14)
;
This based upon the table that was created above.
After running the update then using :-
SELECT strftime('%Y-%m-%d %H:%M', mytimestamp) FROM mytable;
results in :-
Time Strings A time string can be in any of the following formats:
YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM
HH:MM:SS
HH:MM:SS.SSS
now
DDDDDDDDDD
In formats 5 through 7, the "T" is a literal character separating the
date and the time, as required by ISO-8601. Formats 8 through 10 that
specify only a time assume a date of 2000-01-01. Format 11, the string
'now', is converted into the current date and time as obtained from
the xCurrentTime method of the sqlite3_vfs object in use. The 'now'
argument to date and time functions always returns exactly the same
value for multiple invocations within the same sqlite3_step() call.
Universal Coordinated Time (UTC) is used. Format 12 is the Julian day
number expressed as a floating point value.
Formats 2 through 10 may be optionally followed by a timezone
indicator of the form "[+-]HH:MM" or just "Z". The date and time
functions use UTC or "zulu" time internally, and so the "Z" suffix is
a no-op. Any non-zero "HH:MM" suffix is subtracted from the indicated
date and time in order to compute zulu time. For example, all of the
following time strings are equivalent:
2013-10-07 08:23:19.120
2013-10-07T08:23:19.120Z
2013-10-07 04:23:19.120-04:00
2456572.84952685
In formats 4, 7, and 10, the fractional seconds value SS.SSS can have
one or more digits following the decimal point. Exactly three digits
are shown in the examples because only the first three digits are
significant to the result, but the input string can have fewer or more
than three digits and the date/time functions will still operate
correctly. Similarly, format 12 is shown with 10 significant digits,
but the date/time functions will really accept as many or as few
digits as are necessary to represent the Julian day number.
SQL As Understood By SQLite - Date And Time Functions
In my application i am trying to fetch records from a sqlite table with respect to a range of dates selected from the date picker. The records in the table are as follows :
The query formed is as given below :
select * from Order_Master where Order_Date >= '12-04-2015' and Order_Date <= '11-03-2016' And WSS_Code = '1014332'
This query does not return any value which is not the desired result as the dates are in the selected range.
What could possibly be wrong here ? Am i missing something?
Kindly guide me through this. Thanking you in Advance !
Your date format cannot be used for comparisons, because strings are compared lexicographically, i.e., with the first characters compared first.
In this query, you are searching for dates with a month that is at least 12 and, at the same, no larger than 11.
SQLite has no separate data type for dates.
To store dates in a database, you have to choose one of the existing data types (number or text).
When using SQLite's built-in date functions, you must use one of the formats supported by them.
Try this , hope it helps
Change your datatype to text
SELECT * FROM Order_Master WHERE Order_Date BETWEEN '12-04-2015' AND '11-03-2016' AND WSS_Code = '1014332';
As well as your query will also work.
I am storing some data and date that is selected by user in sqlite in dd-MMM-yyyy format in storeDate named column with TEXT type because afaik there is no DATE type directly. Now I want to retrieve the stored data month wise. Suppose I give input as 01-Dec-2013 and build where clause, then I need to get the data of that particular month(Dec, 2013). Can someone Please suggest how to achieve this? My current query is:
Cursor cursor= db.rawQuery("SELECT * FROM "+TABLE_NAME+" "+whereClause+" GROUP BY "+CATEGORY, null);
What should be given at the place of whereClause?
SQLite does not support month names, sadly. You will have to convert it to a month name either using a lookup table, a case statement, or a switch on the presentation layer.
Try this
SELECT strftime('%Y-%m', table_column) FROM `table name` WHERE strftime('%Y-%m', table_column) = '2013-04'
If you want to print the month name only then try this
SELECT case strftime('%m',date_column) when '01' then 'January' when '02' then 'Febuary' when '03' then 'March' when '04' then 'April' when '05' then 'May' when '06' then 'June' when '07' then 'July' when '08' then 'August' when '09' then 'September' when '10' then 'October' when '11' then 'November' when '12' then 'December' else '' end
as month FROM `your_table` WHERE strftime('%m',date_column)='12'
Also take a took at this stuff for more date and time functions in SQLite
Date And Time Functions
You could use MySQL's MONTH() function
SELECT * FROM tbl WHERE MONTH( trans_date ) = 3
My Android app has an SQLite database table with entries as follows:
USER_ID | NAME | MESSAGE | TIMESTAMP
where the timestamp is stored in a String in format:
"2012-10-10T03:14:32+0000"
I'm looking for a way to delete entries older than 3 days.
The table is likely to have less than 3,000 rows at a time.
I'm new to SQL and my question is how can I approach this in SQL for SQLite? Is there a less expensive way to do this in SQL than to iterate all posts in Java?
You can have a look at this doc.
Another way is to use the fact that the date format you use can be sorted directly as a string (lexicographical order).
In java code, you build the string representing the datetime threshold (Now minus 3 days)
And just compare the strings in SQL in the where clause
SELECT *
FROM MyTable
WHERE TIMESTAMP >= 'The date I built in Java'
Most of the time, Timestamps and datetimes are stored as ticks in SQLite, which involves int comparaison (much faster).