Reputation: 11632
I have table with following structure:
And I'm trying to get grouped values between two dates, problem is, that i would like to have also retuned rows for dates which are not in select, for example i have range for
WHERE m.date BETWEEN "2014-09-02" AND "2014-09-10"
But for example in date 2014-09-06 is no related row in table, so in result should be
2014-09-06| 0 | 0 | 0 | 0
How can i do it please? (if is it possible with SQLLite database).
Here is the query which i'm using:
SELECT substr(m.date, 1, 10) as my_date, COUNT(m.ID) AS 'NUMBER_OF_ALL_CALLS',
(SELECT COUNT(*) FROM dialed_calls subq WHERE subq.call_result = 'DONE'
AND substr(m.date, 1, 10) = substr(subq.DATE, 1, 10)) as 'RESULT_DONE',
(SELECT COUNT(*) FROM dialed_calls subq WHERE subq.call_result = 'NOT_INTERESTED'
AND substr(m.date, 1, 10) = substr(subq.DATE, 1, 10)) as 'RESULT_NOT_INTERESTED',
(SELECT COUNT(*) FROM dialed_calls subq WHERE subq.call_result = 'NO_APPOINTMENT'
AND substr(m.date, 1, 10) = substr(subq.DATE, 1, 10)) as 'RESULT_NO_APP'
FROM dialed_calls m
WHERE m.date BETWEEN "2014-09-02" AND "2014-09-05"
GROUP BY my_date
Many thanks for any help.
Table structure:
BEGIN TRANSACTION;
CREATE TABLE dialed_calls(Id integer PRIMARY KEY,
'date' datetime,
'called_number' VARCHAR(45),
'call_result' VARCHAR(45),
'call_duration' INT,
'synced' BOOL);
/* Create few records in this table */
INSERT INTO dialed_calls VALUES(1,'2014-09-02 15:54:34+0200',
'800123456', 'NOT_INTERESTED', 10, 0);
INSERT INTO dialed_calls VALUES(2,'2014-09-02 15:56:30+0200',
'800123456', 'NO_APPOINTMENT', 10, 0);
INSERT INTO dialed_calls VALUES(3,'2014-09-02 16:01:49+0200',
'800123456', 'DONE', 9, 0);
INSERT INTO dialed_calls VALUES(4,'2014-09-02 16:03:03+0200',
'800123456', 'NO_APPOINTMENT', 69, 0);
INSERT INTO dialed_calls VALUES(5,'2014-09-02 18:09:34+0200',
'800123456', 'NO_APPOINTMENT', 3, 0);
INSERT INTO dialed_calls VALUES(6,'2014-09-02 18:54:02+0200',
'123456789', 'NO_APPOINTMENT', 89, 0);
INSERT INTO dialed_calls VALUES(7,'2014-09-02 18:55:25+0200',
'123456789', 'NOT_INTERESTED', 89, 0);
INSERT INTO dialed_calls VALUES(8,'2014-09-03 18:36:58+0200',
'123456789', 'DONE', 185, 0);
INSERT INTO dialed_calls VALUES(9,'2014-09-04 18:36:58+0200',
'123456789', 'DONE', 185, 0);
INSERT INTO dialed_calls VALUES(10,'2014-09-05 18:36:58+0200',
'123456789', 'DONE', 185, 0);
COMMIT;
Upvotes: 0
Views: 971
Reputation: 212
Try this:
SELECT
d.date AS DATE,
IFNULL(NUMBER_OF_ALL_CALLS, 0) AS NUMBER_OF_ALL_CALLS,
IFNULL(RESULT_DONE, 0) AS RESULT_DONE,
IFNULL(RESULT_NOT_INTERESTED, 0) AS RESULT_NOT_INTERESTED,
IFNULL(RESULT_NO_APP, 0) AS RESULT_NO_APP
FROM
(SELECT DATE('1970-01-01', '+' || (t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) || ' days') date FROM
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0,
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4) d
LEFT JOIN
(
SELECT substr(m.date, 1, 10) as my_date, COUNT(m.ID) AS 'NUMBER_OF_ALL_CALLS',
(SELECT COUNT(*) FROM dialed_calls subq WHERE subq.call_result = 'DONE'
AND substr(m.date, 1, 10) = substr(subq.DATE, 1, 10)) as 'RESULT_DONE',
(SELECT COUNT(*) FROM dialed_calls subq WHERE subq.call_result = 'NOT_INTERESTED'
AND substr(m.date, 1, 10) = substr(subq.DATE, 1, 10)) as 'RESULT_NOT_INTERESTED',
(SELECT COUNT(*) FROM dialed_calls subq WHERE subq.call_result = 'NO_APPOINTMENT'
AND substr(m.date, 1, 10) = substr(subq.DATE, 1, 10)) as 'RESULT_NO_APP'
FROM dialed_calls m
GROUP BY my_date
) t
ON d.date = t.my_date
WHERE d.date BETWEEN '2014-09-02' AND '2014-09-10'
ORDER BY d.date;
Above query will first the retrieve the dates between the specified date range and later will join the retrieved values with your table.
Upvotes: 1
Reputation: 1848
to get intermediate dates as the query result you need a table with all the dates in the range. in some rdbms you can populate a temporary table to join with. you will have to compare the date part only (without time).
be careful with your between because the second date has time 00:00:00 and maybe it's not what you meant.
Upvotes: 0
Reputation: 6819
This is a good case for joining to a Calendar table.
http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html Note this is a SQL server link, but you can adapt this to SQLlite.
You could do your calculations, and then right join the results to the calendar table, so that the dates appear with NULL values. Or you could COALESCE() the nulls to something that makes more sense, like 0.
Upvotes: 1