SQLite: How to get table values that match the current month? - android

I have a SQLite table that has one column for an amount of money spent, and one column for when (YYYY-MM-DD) that money was spent. Both columns are strings. How do I write a query that will give me the total amount that was spent this month?
The closest I've come is
select sum(expenseValue)
from expenses_table
where CAST(substr(date,6,2) AS INT) == strftime('%m', 'now ')
which is not an error but also does not produce any value.

Don't do the comparison as integers, do the comparison as strings:
select sum(expenseValue)
from expenses_table
where substr(date, 6, 2) = strftime('%m', 'now')
What might be happening is that "6" (as an integer) is not equal to "06" as a string.

If your date is in the format yyyy-mm-dd, you could use date modifiers to do calculations on dates easily:
SELECT * FROM expense WHERE date > date('now', 'start of month');
In general, you can issue simple queries as such:
SELECT * FROM expense WHERE date > '2016-07-01';
See https://www.sqlite.org/lang_datefunc.html

Apparently strftime('%m%', 'now') returns 07 even though the current month is June. So the correct query for the current month is
select sum(expenseValue)
from expenses_table
where substr(date, 6, 2) = strftime('%m','now', '-1 month').
Thanks anyway to Gordon!

Related

Sqlite get a list of last 30 days, one row per day

I have the date stored in a int field and when I select it I use
strftime('%Y-%m-%d', table.date/1000, 'unixepoch') as date
I need to have data for the past 30 days for charting purposes, this means that I need to have in my final query something like:
2017-01-18 ,2
2017-01-17, 0
2017-01-16, 0
2017-01-15, 1
In my table I only have rows for 18th and 15th Jan. So running a query against it, will only return rows for the days that exists,
2017-01-18 ,2
2017-01-15, 1
However, I need to have rows, with 0 value, for the past 30 days that don't have any values, as a final result. In order to have this, I need a way to union my data with a query that returns
now-1 day, 0
now-2 days ,0
now-3 days, 0
....
for the past 30 days. In this way, when I combine the 2 queries, will results in the desired results.
Using from https://stackoverflow.com/a/32987070/379865
I managed to get the data
WITH RECURSIVE dates(date) AS (
VALUES(date('now'))
UNION ALL
SELECT date(date, '-1 day')
FROM dates
limit 30
)
SELECT date, 0 as value FROM dates;
However I don't know how to union it with my other query since WITH does not seem to go as part of a union all
I'm not entirely sure what you are after but I'll have a shot.
Aggregate by strftime('%Y-%m-%d', table.date/1000, 'unixepoch') and then have a count.
e.g.
SELECT COUNT(*), strftime('%Y-%m-%d', table.date/1000, 'unixepoch') as date FROM table GROUP BY strftime('%Y-%m-%d', table.date/1000, 'unixepoch')
Hopefully this is what you are looking for ..
WITH does go with compound queries:
WITH ...
SELECT date, 0 AS value FROM dates
UNION ALL
SELECT ...;
However, to remove the dummy rows for dates that exist, you should use a join:
WITH ...
SELECT ...
FROM dates
LEFT JOIN (SELECT ...your actual query...)
USING (date);

Select Where date is greater than or equal to today in SQLite

I have dates stored in my Database in a dd/mm/yyyy format and I am looking to only show items where the date is equal to or great than today.
I have tried WHERE date(fixtures.date) >= date('now') but I got no results.
Below is my query, any help would be greatly appreciated
SELECT fixtures.id,
fixtures.team_1_id,
fixtures.team_2_id,
fixtures.date,
fixtures.time,
fixtures.pitch,
teams.team_name,
teams_1.team_name AS awayTeam,
leagues.league_name
FROM fixtures
INNER JOIN teams
ON fixtures.team_1_id = teams.id
INNER JOIN teams AS teams_1
ON fixtures.team_2_id = teams_1.id
INNER JOIN teams_vs_leagues
ON teams.id = teams_vs_leagues.team_id
INNER JOIN leagues
ON teams_vs_leagues.league_id = leagues.id
WHERE date(fixtures.date) >= date('now')
ORDER BY fixtures.date DESC
Why do you say your dates are store in dd/mm/yyyy format? According to SQLite docs
1.2 Date and Time Datatype
SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions.
Basically this query won't work
select 1 where '01-08-2016' >= date('now')
but this will
select 1 where '2016-08-01'>= date('now')
So can you verify if your date fixtures.date is format as 'yyyy-MM-dd' otherwise your query won't work. Additionally remember to use date('now', 'localtime') to get your local time.
If your date is well formated you can try to do something like
SELECT fixtures.id
FROM fixtures
WHERE fixtures.date >= date('now')
if you do get results with this, then the joins are not matching any row.
For further information you can check this answer

How I can get all last year's records of SQLite table

I have a table in which each record has a date. I want to get records based on the last 365 days.
WHERE MYDATE < date('now', '-365 day') is not working
The table has the following:
George 10/4/2016 Pass
John 4/5/2015 Pass
John 19/7/2013 Fail
So I run the above and
I get John with 19/7/2013 and George with 10/4/2016
You should save dates in SQLite format
SELECT
Name
FROM
Persons
WHERE
date <= date('now', '-365 days')
maybe do the job

SQLite query between dates

select * from table_my where my_date between '2014-07-23 00:00:00' and '2014-07-30 00:00:00' order by _id desc
Here is my query, I d like to create this simple date compare query, but not working. This query don't add anything out. Why? How can I compare dates in sqlite?
Try below query using strftime date functions.
SELECT * from table_my
WHERE strftime('%Y-%m-%d', my_date )
between
strftime('%Y-%m-%d', '2014-07-23')
and
strftime ('%Y-%m-%d', '2014-07-30');
EDIT:
To use with hours and minutes, you can try something like:
SELECT * from table_my
WHERE strftime('%Y-%m-%d %H:%M', my_date )
between
strftime('%Y-%m-%d %H:%M', '2014-07-23 11:22')
and
strftime ('%Y-%m-%d %H:%M', '2014-07-23 11:25');
select * from table_my where my_date between '2014-07-30' and '2014-07-23' order by _id desc
use above query may it will work to you i also got such kind of problem during coding i think it is coming cause your using lower value before greater value
may it will help you just chek it
i just swiped the two dates also i removed timestamp

How do you count the number of consecutive dates in a table?

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.

Categories

Resources