I have a problem in displaying the data in my application for each week?
I can show the data by day using this code in my SQLite
SELECT substr(_id, 1, 7) as _id, sum(value) as total FROM pd_table GROUP BY _id order by _id desc
I was also able to display the data based on the month by using this code
SELECT substr(_id, 1, 10) as _id, sum(value) as total FROM pd_table GROUP BY _id order by _id desc
_id using SimpleDateFormat ("yyyy-MM-dd HH: mm: ss")
now i want to display it every week. How?
Any answer is very useful for me :)
SQLite has internal date/time formatting function strftime, and one of possible format option is a week number. So your query should look like this:
SELECT strftime('%Y-%W',_id) as week_of_year, sum(value) as total
FROM pd_table
GROUP BY week_of_year order by _id desc
Though I didn't try it on Android. See more here: http://sqlite.org/lang_datefunc.html
Related
I am storing date format in sqlite table, I want sort by date from table.
Every record in my SQLite database contains a column which contains a date stored as a string in the format 'yyyy-MM-dd HH:mm:ss'.
I am sharing my table structure. I am using this query to sort by datetime it not sorting by time but sort by date is working fine.
select *
from messages_table
where id = '444'
order by datetime(date_time) asc
I am storing datetime as string in my below table
and I am getting the below wrong sorting by time output please see my date_time column in the picture, anyone guide me.
I have a similar problem with the TIME datatype.
If I enter time values correctly, such as 8:00 or 13:00, they are sorted as strings in an ORDER BY clause, in effect as "800" and "1300", where the string "1300" is sorted before "800" in ascending order.
One solution is to pad all times with a leading 0, so we get "0800" and "1300" which will be sorted time wise correctly.
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
I want to get the latest 5 records in my table, so far i tried this but, it did not work out very well. So, what is the cleanest and efficient way to get last 5 records in the table ?
"select * from (select * from People order by Date DESC limit 5) order by Date ASC;"
Your query works just fine.
To make it efficient, ensure that there is an index on the Date column; then SQLite will just read the last five entries from the index and the table and does not need to scan the entire table.
If this table has an autoincrementing ID column, and if "latest" means the insertion order, then you can use that ID for sorting; this will be as efficient as your original query with an index on Date:
SELECT * FROM (SELECT * FROM People
ORDER BY _id DESC
LIMIT 5)
ORDER BY Date ASC
I have seen number of post about storing date.
I am still not getting the fine and exact approach about saving it to a sqlite database.
I am able to store it, but during sorting I need to consider only month and day just like birthday where years doesn't matter.
What will be the query if I want to get the row whose date is 2 or 3 days in advance, like 2nd march row if searched on 28 Feb?
You should start by checking out the SQLite documentation of date & time functions.
For instance, to solve your problem "And what will be the query if i want to get the row whose date is 2 or 3 days in advance" you'd use julian day calculations, such as this example that you can execute directly in the sqlite3 shell:
create TABLE example (_id INTEGER PRIMARY KEY NOT NULL, date TEXT NOT NULL);
insert into example (date) values ('2011-01-02');
insert into example (date) values ('2011-04-02');
insert into example (date) values ('2012-02-26');
insert into example (date) values ('2012-02-27');
insert into example (date) values ('2012-02-28');
insert into example (date) values ('2012-02-29');
insert into example (date) values ('2012-03-01');
insert into example (date) values ('2012-03-02');
insert into example (date) values ('2012-03-03');
select date from example where julianday(date) - julianday('now') < 3 AND julianday(date) - julianday('now') > 0;
This would return (given that "today" is feb 28th) all the days that are one, two or three days in the future:
2012-02-29
2012-03-01
2012-03-02
Edit: To only return rows, regardless of year, you could do something like this - using a VIEW (again, exampl is directly in SQLite):
create view v_example as select _id, date,
strftime("%Y", 'now')||'-'||strftime("%m-%d", date) as v_date from example;
This VIEW would return the date & times in your database "rebased" on the current year - which, of course could introduce all manner of wonky behavior with leap years.
You can select all the dates like this in that case:
select date from v_example where
julianday(v_date) - julianday('now') < 3 AND
julianday(v_date) - julianday('now') > 0 ORDER BY v_date;
Which would return:
2012-02-29
2012-03-01
2001-03-01
2012-03-02
2010-03-02
If you want to sort by day and month consider storing the date as string in the format ddMMyyyy (you need two digits for day and month, otherwise the sorting will be flawed). Sorting by increasing values will give you dates sorted by day and month (and then year).
You can even do range query with string but you have to compute the query string.
Alternatively you may store the date as milliseconds in an additional column (this is the usual format for dates in the database) and do the range queries more easily with integer arithmetic.
One option is to use strftime() in SQLite to strip of the year and then do a comparison.
select * from sometable where strftime('%m-%d', somecolumn) = '02-28'
This will do a query of all rows for February 28th. But performance might be hurt if you have a large table and need to do a string conversion of every row for comparison. Maybe store the day and month in two additional columns if this query is performed often?
In my Android App I need to keep track of the longest streak, and current streak, of consecutive dates that are saved in a database table. I don't even know where to start to get this to work. The best I can come up with is to query every row in the table and iterate through all of them programmatically to find where there's a gap. Not very efficient. Anyone have any better ideas?
Here is an SQL only solution that I thought was really cool. Assuming the dates in your table are unique (not that it would be too hard to just group on them) you can use the method adapted from here http://www.sqlteam.com/article/detecting-runs-or-streaks-in-your-data. I ran through the example and there are some syntax errors, so hopefully I didn't repeat them in my answer below. I probably used some reserved keywords, so you may need to adapt that.
First create a table of Dates that is significantly large to cover your needs. I'm not sure what the best method for SQLite is, but in SQL Server you can insert integers into a Datetime field and it will do an implicit conversion of integers to dates. There are many methods to insert integers into tables...
Anyway, once the Dates table is created, do a left join from your Dates table to your Streak table using your min and max dates from your streak table as your range limiter. You will then have the following code.
Let’s call it SQL 0
SELECT Dates.Date,
CASE
WHEN StreakTable.DATE IS NULL THEN 0
ELSE 1
END AS Result
FROM Dates
LEFT JOIN StreakTable
ON Dates.DATE = StreakTable.DATE
WHERE Dates.DATE BETWEEN (SELECT MIN(DATE) AS MinDate
FROM StreakTable) AND (SELECT MAX(DATE) AS MaxDate
FROM StreakTable)
Let’s call the following SQL 1
SELECT Date,
Result,
(SELECT COUNT(*)
FROM (SQL 0) S
WHERE S.Result <> SV.Result
AND S.GameDate <= SV.GameDate) AS RunGroup
FROM (SQL 0) SV
Let’s call the following SQL 2
SELECT Result,
MIN(Date) AS StartDate,
MAX(Date) AS EndDate,
COUNT(*) AS Days
FROM (SQL 1) A
GROUP BY Result,
RunGroup
ORDER BY MIN(Date)
At this point you can do some pretty cool stuff like answer:
What was the longest streak?
SELECT TOP 1 *
FROM (SQL 2) A
WHERE Result = 1
ORDER BY Games DESC
What is the current streak as of the most recent date?
SELECT *
FROM (SQL2) A
WHERE EndDate = (SELECT Max(Date)
FROM Streak)
How many streaks of 3 or more did we have?
SELECT Result,
COUNT(*) as NumberOfStreaks
FROM (SQL 2) A
GROUP BY Result
WHERE Days >= 3
Basically you have a month and days in a month
so you just compare the days count to the needed number.
If there's a gap you can easily find it out by substracting the count from days in a month. E.g. you have count(days_visited) where month=1
and it returns you 20 days but January has 31 so there's a gap in 11 days and here're the date functions of sqlite
http://www.sqlite.org/lang_datefunc.html
You can use following functions
like SELECT date('now','start of year','+9 months','weekday 2');
EDIT
sorry everyone solution is ugly. it is I know.
create table visits(day_visited timestamp,visited int);
You create a record everyday in this table indicating
whether a user was online or offline with
'now',1 or 0 (online/offline). Then you run through there records.
Your records for month will be an int array with 1s and 0s.
called vistedrecordsformonth
pseudo code:
int online=0;
int offline=0;
for(int i=0;i<vistedrecordsformonth.size();i++){
boolean flag=false;
if(vistedrecordsformonth[i]==1){ //visited
if(!flag&&i!=0) //check for flag and not 0 index to insert a record
{
streaksMap.put(online,offline); //or insert a record into another streakmap or table
online=0;
offline=0;
}
flag=true;
online++;
}
else{
flag=false;
offline++;
}
} //end of for
The map or table will contain a pair of online=offline days for a month.
with usual order by you can see what was the biggest streak in online or offline days.
It is ugly I know I'm sure there should be something more elegant but as
quick and dirty it should work.
hope it helps abit.