On 2016/05/12 12:20 AM, Jonathan wrote:
> Hi List,
>     Let's say I have a table with a simplified structure like this:
> /    create table my_table(//
> //        time_date DATE,//
> //        num INTEGER//
> //    );/
>
>     My data has three rows and looks like this:
> /    2016-01-01; 3//
> //    2016-01-01; 1//
> //    2016-01-03; 2/
>
>     I want to return the sum  of "num" for any given time_date, 
> grouped by day, so I have:
>
> /       SELECT time_date,//
> //              sum( num ) AS sum_num//
> //         FROM my_table//
> //
> //        GROUP BY time_date//
> //        ORDER BY time_date ASC/
>
>     This returns:
> /    2016-01-01; 4//
> //    2016-01-03; 2/
>
>     But what I want is for a value of "0" to be returned for the 
> "missing" date 2016-01-02:
> /    2016-01-01; 4//
> //    2016-01-02; 0//
> //    2016-01-03; 2/
>
>     Is this possible? I'm imagining a sub-query with a start and end 
> date ("now") but I can't think of how to get SQLite to return data 
> that it doesn't have.
>     Does anyone have any suggestions for how to achieve this?

A simple CTE can do this as follows: (Note - it can be done with less 
iterations, but this example makes clear what is happening)

  -- SQLite version 3.9.2  [ Release: 2015-11-02 ]  on SQLitespeed 
version 2.0.2.4.

   -- Script Items: 4          Parameter Count: 0
   -- 2016-05-12 00:53:22.084  |  [Info]       Script Initialized, 
Started executing...
   -- 
================================================================================================

CREATE TABLE my_table(
    time_date NUMERIC,
    num INTEGER
  );

INSERT INTO my_table VALUES
('2016-01-01 00:00:00', 3),
('2016-01-01 00:00:00', 1),
('2016-01-03 00:00:00', 2);

-- Without CTE:
SELECT time_date, sum( num ) AS sum_num
   FROM my_table
  GROUP BY time_date
  ORDER BY time_date ASC
;


   -- time_date             | sum_num
   -- --------------------- | -------
   -- 2016-01-01 00:00:00   |    4
   -- 2016-01-03 00:00:00   |    2


-- With CTE:
WITH dtRange(minDT,maxDT) AS (
     SELECT MIN(time_date), MAX(time_date) FROM my_table
), dtAll(dt) AS (
     SELECT minDT FROM dtRange
     UNION ALL
     SELECT datetime(dt,'+1 day') FROM dtAll,dtRange WHERE dt < maxDT
), my_full(time_date, num) AS (
     SELECT time_date, num FROM my_table
     UNION ALL
     SELECT DT, 0 FROM dtAll
)
SELECT date(time_date) as time_date, sum(num) AS sum_num
   FROM my_full
  GROUP BY time_date
  ORDER BY time_date ASC
;


   -- time_date    | sum_num
   -- ------------ | -------
   -- 2016-01-01   |    4
   -- 2016-01-02   |    0
   -- 2016-01-03   |    2


Cheers!
Ryan

Reply via email to