Thursday, February 6, 2014

Group by date time month or year and sum in SQLite

I have a database table that contains a few fields like transaction date which is a string representing date time, transaction amount, and transaction status in a SQLite database present on an Android device. The SQL Lite database contains a table named "trx_log", the table has fields _id int, trxDateTime text, trxTargetNumber text, trxAmount number, trxStatus text. A graphical representation of the table structure is given below:
sqlite-android-search-by-year-group-by-month

SQLLite Query Sum and Group By Year

How to calculate sum of all transactions that took place in the year 2014? What is the SQLite query for group by results by year and calculating a sum? We are going to use SQLite aggregate function SUM in and combine it with GROUP BY Clause

SELECT strftime('%Y', trxDateTime) as valYear, SUM(trxAmount) 
FROM trx_log WHERE valYear = '2014' GROUP BY valYear



I have used SQLite strftime function along with format string '%Y' . As a result, SQLite query returns '2014' in result set column named valYear which is used in WHERE clause and GROUP BY clause as well.







SQLLite Query Sum and Group By Month and Year

Now suppose I want to calculatnce the sum of all transaction that took place in all months of 2014 and show those as a column. SQLite with SUM aggregate function and a slightly different where clause and GROUP BY will be used
SELECT strftime('%m', trxDateTime) as valMonth, 
SUM(trxAmount) as valTotalMonth 
FROM trx_log 
WHERE strftime('%Y', trxDateTime)='2014' GROUP BY valMonth

Please note that the data set returned by this SQLLite against this SQL query will have two result set columns valMonth and valTotalMonth, the column valMonth will have numeric values from 01 to 12.

SQLLite Query Sum and Group By Day, Month, and Year

Next up we got a query to calculate sum of transactions that took place in a month say February which will be represented by string '02' in SQLite, further more we want to group the sums or totals by day. Like how many transactions happened on day 01 how many on day 02 and so on. The query for the task is given below.
SELECT strftime('%d', trxDateTime) as valDay, 
SUM(trxAmount) as valTotalDay 
FROM trx_log 
WHERE 
strftime('%Y', trxDateTime)='2014' 
AND strftime('%m', trxDateTime) ='02'
GROUP BY valDay
SQLite does not sport a separate date time data type, you must store the date time related data in one of two formats, first is the date string format which is:
YYYY-MM-dd HH:mm:ss.SS

Second is plain NUMERIC field type storing stuff in Unix timestamps. Be careful when you're calculating timestamps using Android or Desktop Java Date.getDate() function it's representing the timestamps in millisecond. You'll have to divide the figure by 1000 before performing any calculation on it.

Use the method SQLiteDatabase.rawQuery to execute these queries on your SQLite database.

SQLite is such a popular in memory database, it's being used on both Apple iOS and Google Android devices.

I'm working as a freelance programmer through ODesk.com, I have a strong profile over there. Feel free to ping me if you need an Android app.

https://www.odesk.com/users/~012d73aa92fad47188

PS: The table structure screen shot is taken using SQLite Browser software.

3 comments:

  1. That's ok, but, how can I list all months or all days even with zero value, like this:

    Jan Feb Mar
    0 5 0

    ...

    Thanks

    ReplyDelete
  2. WITH month_table as (
    SELECT '01' as month,'Jan' UNION ALL
    SELECT '02' as month,'Feb' UNION ALL
    SELECT '03' as month,'Mar' UNION ALL
    SELECT '04' as month,'Apr' UNION ALL
    SELECT '05' as month,'May' UNION ALL
    SELECT '06' as month,'Jun' UNION ALL
    SELECT '07' as month,'Jul' UNION ALL
    SELECT '08' as month,'Aug' UNION ALL
    SELECT '09' as month,'Sep' UNION ALL
    SELECT '10' as month,'Oct' UNION ALL
    SELECT '11' as month,'Nov' UNION ALL
    SELECT '12' as month,'Dec')


    SELECT t.month,sum(f.value) FROM month_table t,finance f where user_id = 4 and strftime('%Y', f.dt_lancamento) = '2015' and strftime('%m', f.dt_lancamento) = t.month group by t.month;

    ReplyDelete
  3. Dear Omar, I guess you've answered your question :)
    Otherwise, I didn't know how to do it. Thank you very much for your contribution.
    Naeem.

    ReplyDelete

Feel free to talk back...