MySql version 8.0.17 average datediff - mysql

In the table stored an a database MySql version 8.0.17 I have these four field set as datetime type
+---------------------+-----------+---------------------+------------+
| tdate | tigx | tclosed | tcompleted |
+---------------------+-----------+---------------------+------------+
the field tdate never null;
the field tigx it could be null;
the field tclosed it could be null;
the field tcompleted it could be null;
Now I get the average datediff respecting this sequence
If tclosed IS NOT NULL AND tcompleted IS NOT NULL AND tigx IS NOT NULL the AVG is ROUND(AVG(DATEDIFF(tclosed, tdate)),1)
If tclosed IS NULL AND tcompleted IS NULL AND tigx IS NULL the AVG is ROUND(AVG(DATEDIFF(CURDATE(), tdate)),1)
But if at least one of the fields tigx or tclosed or tcompleted is null I have to take the first populated field from tigx or tclosed or tcompleted... and using this first populated field for get the average datediff.
Here I am stuck... any suggestion?
My query below
SELECT
tkt,
tdate,
tstate,
tigx,
tclosed,
tcompleted,
CASE
WHEN ( tclosed IS NOT NULL AND tcompleted IS NOT NULL AND tigx IS NOT NULL ) THEN
ROUND( AVG( DATEDIFF( tclosed, tdate )), 1 )
WHEN ( tclosed IS NULL AND tcompleted IS NULL AND tigx IS NULL ) THEN
ROUND( AVG( DATEDIFF( CURDATE(), tdate )), 1 )
END AS `avg`
FROM
`tbl_c`
WHERE
NOT ( `tkt` LIKE '%I%' OR `tkt` LIKE '%L%' AND tstate IN ( 'Closed' ) AND tigx IS NULL AND tclosed IS NULL AND tcompleted IS NULL )
ORDER BY
tdate DESC;
UPDATE 2
SELECT
tkt,
tdate,
tstate,
tigx,
tclosed,
tcompleted,
CASE
WHEN ( tclosed IS NOT NULL AND tcompleted IS NOT NULL AND tigx IS NOT NULL ) THEN
ROUND( AVG( DATEDIFF( tclosed, tdate )), 1 )
WHEN ( tclosed IS NULL AND tcompleted IS NULL AND tigx IS NULL ) THEN
ROUND( AVG( DATEDIFF( CURDATE(), tdate )), 1 )
WHEN COALESCE(tclosed,tcompleted,tigx) THEN
ROUND(AVG(DATEDIFF(?????, tdate)),1)
END AS `avg`
FROM
`tbl_c`
WHERE
NOT ( `tkt` LIKE '%I%' OR `tkt` LIKE '%L%' AND tstate IN ( 'Closed' ) AND tigx IS NULL AND tclosed IS NULL AND tcompleted IS NULL )
ORDER BY
tdate DESC;
UPDATE
SELECT
tkt,
tdate,
tstate,
tigx,
tclosed,
tcompleted,
CASE
WHEN ( tclosed IS NOT NULL AND tcompleted IS NOT NULL AND tigx IS NOT NULL ) THEN
ROUND( AVG( DATEDIFF( tclosed, tdate )), 1 )
WHEN ( tclosed IS NULL AND tcompleted IS NULL AND tigx IS NULL ) THEN
ROUND( AVG( DATEDIFF( CURDATE(), tdate )), 1 )
WHEN COALESCE ( tclosed ) THEN
ROUND( AVG( DATEDIFF( tcompleted, tdate )), 1 )
WHEN COALESCE ( tcompleted ) THEN
ROUND( AVG( DATEDIFF( tigx, tdate )), 1 )
WHEN COALESCE ( tigx ) THEN
ROUND( AVG( DATEDIFF( tclosed, tdate )), 1 )
END AS `avg`
FROM
`tbl_c`
WHERE
NOT ( `tkt` LIKE '%I%' OR `tkt` LIKE '%L%' AND tstate IN ( 'Closed' ) AND tigx IS NULL AND tclosed IS NULL AND tcompleted IS NULL )
ORDER BY
tdate DESC;

You seem to be struggling with this, following is at least conceptually correct(not sure about the bracketing and outcome)
CASE
WHEN ( tclosed IS NOT NULL AND tcompleted IS NOT NULL AND tigx IS NOT NULL ) THEN
ROUND( AVG( DATEDIFF( tclosed, tdate )), 1 )
WHEN ( tclosed IS NULL AND tcompleted IS NULL AND tigx IS NULL ) THEN
ROUND( AVG( DATEDIFF( CURDATE(), tdate )), 1 )
else
ROUND(AVG(DATEDIFF(COALESCE(tclosed,tcompleted,tigx), tdate)),1
END AS `avg`

I have had a go at this one for you, but I have had to make 2 assumptions:
Dates have rising values across the columns: tdate <= tigx <= tclosed <= tcompleted
All date values are <= CURRENT_DATE
Given those assumptions are correct, you might like to have a look at this. My solution is for you to create a view to handle your date / null logic. I hope it helps:
/*
Create some test data
need this number generator to create data rows
*/
CREATE OR REPLACE VIEW `number_generator_16` AS
SELECT 0 AS `n`
UNION ALL SELECT 1 AS `1`
UNION ALL SELECT 2 AS `2`
UNION ALL SELECT 3 AS `3`
UNION ALL SELECT 4 AS `4`
UNION ALL SELECT 5 AS `5`
UNION ALL SELECT 6 AS `6`
UNION ALL SELECT 7 AS `7`
UNION ALL SELECT 8 AS `8`
UNION ALL SELECT 9 AS `9`
UNION ALL SELECT 10 AS `10`
UNION ALL SELECT 11 AS `11`
UNION ALL SELECT 12 AS `12`
UNION ALL SELECT 13 AS `13`
UNION ALL SELECT 14 AS `14`
UNION ALL SELECT 15 AS `15`
;
/*Create a table to contain test data*/
DROP TABLE IF EXISTS `a_testdatestdate`;
CREATE TABLE `a_testdatestdate` (
`n` INT(10) SIGNED NOT NULL,
`tdate` DATE NOT NULL,
`tigx` DATE DEFAULT NULL,
`tclosed` DATE DEFAULT NULL,
`tcompleted` DATE DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;
/*
(Truncate - if necessary) and repopulate
TRUNCATE TABLE `a_testdatestdate`;
This statement generates a series of 100 rows where
there is always a value in tdate
the other 4 columns are populated with rising date values
Populated with data in columns 2/3/4/(2-3)/(2-4)/(3-4)/(2-3-4)
ASSUMPTIONS:
1) dates have rising values across the columns: tdate <= tigx <= tclosed <= tcompleted
2) all date values are <= CURRENT_DATE
*/
SET #STARTDATE = DATE_ADD(CURRENT_DATE, INTERVAL -200 DAY);
INSERT INTO `a_testdatestdate` (`n`, `tdate`, `tigx`, `tclosed`, `tcompleted`)
SELECT
`n`.`n`,
DATE_FORMAT(DATE_ADD( #STARTDATE, INTERVAL `n`.`n` DAY),"%Y-%m-%d") AS `tDate`
, CASE
WHEN n.n BETWEEN 10 AND 40 THEN DATE_FORMAT(DATE_ADD( #STARTDATE, INTERVAL `n`.`n` + 1 DAY),"%Y-%m-%d")
WHEN n.n BETWEEN 70 AND 80 THEN DATE_FORMAT(DATE_ADD( #STARTDATE, INTERVAL `n`.`n` + 2 DAY),"%Y-%m-%d")
ELSE NULL
END
, CASE
WHEN n.n BETWEEN 30 AND 50 THEN DATE_FORMAT(DATE_ADD( #STARTDATE, INTERVAL `n`.`n` + 3 DAY),"%Y-%m-%d")
WHEN n.n BETWEEN 90 AND 100 THEN DATE_FORMAT(DATE_ADD( #STARTDATE, INTERVAL `n`.`n` + 4 DAY),"%Y-%m-%d")
ELSE NULL
END
, CASE
WHEN n.n BETWEEN 35 AND 60 THEN DATE_FORMAT(DATE_ADD( CURRENT_DATE, INTERVAL `n`.`n` + 6 DAY),"%Y-%m-%d")
WHEN n.n BETWEEN 70 AND 80 THEN DATE_FORMAT(DATE_ADD( CURRENT_DATE, INTERVAL `n`.`n` + 7 DAY),"%Y-%m-%d")
ELSE NULL
END
FROM (
SELECT
((`hi`.`n` << 4) | `lo`.`n`) AS `n`
FROM (`number_generator_16` `lo`
JOIN `number_generator_16` `hi`)
) `n`
WHERE n.n <100
;
/*
review test data
SELECT * FROM a_testdatestdate;
Create a view to handle your logic around dates and NULL values
*/
DROP VIEW IF EXISTS v_testdatestdate;
CREATE OR REPLACE VIEW v_testdatestdate AS SELECT
n,
tdate,
CASE
WHEN ISNULL(tigx) AND ISNULL(tclosed) AND ISNULL(tcompleted) THEN CURRENT_DATE
WHEN NOT ISNULL(tigx) AND NOT ISNULL(tclosed) AND NOT ISNULL(tcompleted) THEN `tclosed`
ELSE LEAST(IFNULL(tigx, CURRENT_DATE), IFNULL(tclosed, CURRENT_DATE), IFNULL(tcompleted, CURRENT_DATE))
END AS dte
FROM a_testdatestdate;
/*
Then generate your averages from a statement like this
I have left the statement in this state so you can unpick it to suit your requirements
*/
SELECT
ROUND(AVG(`DateDiff`),1)
FROM
(
SELECT
DATEDIFF(dte, tdate) AS `DateDiff`
FROM v_testdatestdate V
) B
;
--> Result = 57.9 in this case.

Related

Get active users by month

Using MySQL, I'm trying to get the number of active users I have in any given month. I have a table with ActivationDate and TerminationDate columns, and if the month being counted is after the ActivationDate and TerminationDate is null, then the user is active and should be counted. I would like to summarize these amounts by month. I'm thinking I could just sum each side and calculate the total but breaking that down won't give me a running total. I've tried with window functions, but I don't have enough experience with them to know exactly what I'm doing wrong and I'm not certain how to ask the right question.
So for instance, if I have the following data...
UserId ActivationDate TerminationDate
1 2020-01-01 null
2 2020-01-15 null
3 2020-01-20 2020-01-30
4 2020-02-01 null
5 2020-02-14 2020-02-27
6 2020-02-15 2020-02-28
7 2020-03-02 null
8 2020-03-05 null
9 2020-03-20 2020-03-21
I would like my results to be similar to:
2020-01 2 (there are 2 active users, since one signed up but cancelled before the end of the month)
2020-02 3 (2 from the previous month, plus 1 that signed up this month and is still active)
2020-03 5 (3 from previous, 2 new, 1 cancellation)
You can unpivot, then aggregate and sum. In MySQL 8.0.14 or higher, you can use a lateral join:
select date_format(x.dt, '%Y-%m-01') as dt_month,
sum(sum(cnt)) over(order by date_format(x.dt, '%Y-%m-01')) as cnt_active_users
from mytable t
cross join lateral (
select t.activationdate as dt, 1 as cnt
union all select t.terminationdate, -1
) x
where x.dt is not null
group by dt_month
order by dt_month
In earlier 8.x versions:
select date_format(x.dt, '%Y-%m-01') as dt_month,
sum(sum(cnt)) over(order by date_format(x.dt, '%Y-%m-01')) as cnt_active_users
from (
select activationdate as dt, 1 as cnt from from mytable
union all select terminationdate, -1 from mytable
) x
where x.dt is not null
group by dt_month
order by dt_month
You don't say what version of MySQL. If you're using 8.0, this should work:
create table userdates (
UserId int not null,
ActivationDate date not null,
TerminationDate date null
);
insert into userdates (UserId, ActivationDate, TerminationDate)
values
(1, cast("2020-01-01" as date), null )
, (2, cast("2020-01-15" as date), null )
, (3, cast("2020-01-20" as date), cast("2020-01-30" as date))
, (4, cast("2020-02-01" as date), null )
, (5, cast("2020-02-14" as date), cast("2020-02-27" as date))
, (6, cast("2020-02-15" as date), cast("2020-02-28" as date))
, (7, cast("2020-03-02" as date), null )
, (8, cast("2020-03-05" as date), null )
, (9, cast("2020-03-20" as date), cast("2020-03-21" as date))
, (10, cast("2020-07-20" as date), null)
, (11, cast("2019-09-12" as date), cast("2019-09-14" as date));
WITH RECURSIVE d (dt)
AS (
SELECT cast("2019-01-01" as date)
UNION ALL
SELECT date_add(dt, interval 1 month)
FROM d
WHERE dt < cast("2020-12-01" as date)
)
select d.dt
, count(distinct ud.UserId) as UserCount
from userdates ud
right outer join d on d.dt >= date_format(ud.ActivationDate, '%Y-%m-01')
and (d.dt <= ud.TerminationDate or ud.TerminationDate is null)
group by d.dt;

Show all data in a date range using MYSQL recursive function

I'm trying to get a list of sales for the past 6 months and get 0 values if I have no data for a specific month. So I'm using recursive_all_dates to generate a date range for the past 6 months which works great:
with recursive all_dates(dt) as (
-- anchor
select DATE_SUB(now(), INTERVAL 6 MONTH) dt
union all
-- recursion with stop condition
select dt + interval 1 month from all_dates where dt + interval 1 month <= DATE(now())
)
select DATE_FORMAT(dt, '%Y-%m') as ym from all_dates
This will return:
ym
------
2019-10
2019-11
2019-12
2020-01
2020-02
2020-03
2020-04
Now I want to left join this with my real data:
with recursive all_dates(dt) as (
-- anchor
select DATE_SUB(now(), INTERVAL 6 MONTH) dt
union all
-- recursion with stop condition
select dt + interval 1 month from all_dates where dt + interval 1 month <= now()
)
SELECT
DATE_FORMAT(ad.dt, '%Y-%m') as ym,
sum(profit) as profit
FROM
all_dates as ad
LEFT JOIN organisation_invoices as i
ON
DATE_FORMAT(ad.dt, '%Y-%m') = DATE_FORMAT(i.issue_date, '%Y-%m')
JOIN (
SELECT
invoice_id,
SUM(value) as profit
FROM organisation_invoice_services isrv
GROUP BY invoice_id
) isrv
ON i.id = isrv.invoice_id
WHERE
i.organisation_id = '4b166dbe-d99d-5091-abdd-95b83330ed3a' AND
i.issue_date >= DATE_SUB(NOW(), INTERVAL 6 MONTH)
GROUP BY `ym`
ORDER BY `ym` ASC
But I still only get the populated months:
ym profit
------------------
2019-12 8791
2020-02 302
2020-04 10452
The desired result:
ym profit
------------------
2019-10 0
2019-11 0
2019-12 8791
2020-01 0
2020-02 302
2020-03 0
2020-04 10452
What am I missing?
Edit: Sample data set and fiddle:
CREATE TABLE `organisation_invoices` (
`id` varchar(255) NOT NULL,
`organisation_id` varchar(255) NOT NULL,
`issue_date` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `organisation_invoice_services` (
`id` varchar(255) NOT NULL,
`organisation_id` varchar(255) NOT NULL,
`invoice_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`qty` float NOT NULL,
`value` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `organisation_invoices` (id, organisation_id, issue_date)
VALUES ('e11cec69-138f-4e20-88e5-5430b6c8d0a1', '4b166dbe-d99d-5091-abdd-95b83330ed3a', '2020-01-20');
INSERT INTO `organisation_invoice_services` (id, organisation_id, invoice_id, qty, `value`)
VALUES ('fe45dfd67-138f-4e20-88e5-5430b6c8d0a1', '4b166dbe-d99d-5091-abdd-95b83330ed3a', 'e11cec69-138f-4e20-88e5-5430b6c8d0a1', 1, 1000);
https://www.db-fiddle.com/f/dibyQi31CBtr2Cr8vjJA8i/0
You can use the following:
with recursive all_dates(dt) as (
-- anchor
select DATE_SUB(now(), INTERVAL 6 MONTH) dt
union all
-- recursion with stop condition
select dt + interval 1 month from all_dates where dt + interval 1 month <= now()
)
SELECT DATE_FORMAT(ad.dt, '%Y-%m') as ym, IFNULL(sum(profit),0) as profit
FROM all_dates as ad
LEFT JOIN organisation_invoices as i
ON DATE_FORMAT(ad.dt, '%Y-%m') = DATE_FORMAT(i.issue_date, '%Y-%m')
LEFT JOIN (
SELECT
invoice_id,
SUM(value) as profit
FROM organisation_invoice_services isrv
GROUP BY invoice_id
) isrv
ON i.id = isrv.invoice_id
WHERE
(i.organisation_id = '4b166dbe-d99d-5091-abdd-95b83330ed3a' AND
i.issue_date >= DATE_SUB(NOW(), INTERVAL 6 MONTH)) OR i.organisation_id IS NULL
GROUP BY `ym`
ORDER BY `ym` ASC
demo on dbfiddle.uk
Changes:
The conditions on the WHERE clause change the behaviour of your LEFT JOIN. Since you check for a specific organization_id, you only get matches between your month table and data (the LEFT JOIN behaves like a INNER JOIN). You need the following WHERE clause instead:
WHERE (i.organisation_id = '4b166dbe-d99d-5091-abdd-95b83330ed3a' AND
i.issue_date >= DATE_SUB(NOW(), INTERVAL 6 MONTH)) OR i.organisation_id IS NULL
You also have to change the second JOIN to a LEFT JOIN.

How to select data from 1 to 5 days with Group By

I've tried it here but I could not, I can only display the total.
I have a download table and a program table.
Every time I download a program I record the date and time, I need to do a grouping of downloaded programs and then 5 columns with the dates, here's an example.
PROGRAMA | HOJE | ONTEM| 2 DIAS | 3 DIAS | 4 DIAS
Programa 1 11 110 55 66 12
Programa 2 25 140 60 90 12
Programa 3 10 20 20 10 10
TOTAL 46 270 135 166 32
Below is my query
select `k`.`app_id` AS `app_id`,`b`.`aplicativo` AS `aplicativo`,count(0) AS `HOJE`,
(select count(0) AS `count(*)` from (`registration` `a` join `aplicativos` `b`) where `k`.`app_id`= `b`.`id` and created_at > (cast(now() as date) - interval 1 day) and (`a`.`created_at` < cast(now() as date)- interval 0 day) ) as ONTEM ,
(select count(0) AS `count(*)` from (`registration` `a` join `aplicativos` `b`) where `k`.`app_id` = `b`.`id`
and created_at > (cast(now() as date) - interval 2 day) and (`a`.`created_at` < cast(now() as date)- interval 1 day) ) as 2_DIAS_ANTES ,
(select count(0) AS `count(*)` from (`registration` `a` join `aplicativos` `b`) where `k`.`app_id` = `b`.`id`
and created_at > (cast(now() as date) - interval 3 day) and (`a`.`created_at` < cast(now() as date)- interval 2 day) ) as 3_DIAS_ANTES ,
(select count(0) AS `count(*)` from (`registration` `a` join `aplicativos` `b`) where `k`.`app_id` = `b`.`id`
and created_at > (cast(now() as date) - interval 4 day) and (`a`.`created_at` < cast(now() as date)- interval 3 day) ) as 4_DIAS_ANTES ,
(select count(0) AS `count(*)` from (`registration` `a` join `aplicativos` `b`) where `k`.`app_id` = `b`.`id`
and created_at > (cast(now() as date) - interval 5 day) and (`a`.`created_at` < cast(now() as date)- interval 4 day) ) as 5_DIAS_ANTES
from (`registration` `k` join `aplicativos` `b`) where ((`k`.`app_id` = `b`.`id`) and (`k`.`created_at` > (cast(now() as date) - interval 0 day)))
group by `b`.`aplicativo`
Table structure
Table aplicativos
CREATE TABLE IF NOT EXISTS `aplicativos` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_usuario` int(11) NOT NULL,
`aplicativo` varchar(200) NOT NULL,
`link` varchar(400) NOT NULL,
`quantidade_notificacoes` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;
Table registration
CREATE TABLE IF NOT EXISTS `registration` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`gcm_regid` varchar(300) NOT NULL,
`app_id` int(11) NOT NULL,
`email` varchar(200) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=73876 ;
Here is one approach for MySQL:
SELECT a.aplicativo as PROGRAMA,
sum(Date(r.created_at) = CURDATE()) AS HOJE,
sum(date(r.created_at) = DATE_SUB(CURDATE(), INTERVAL 1 DAY), 1, 0)) AS ONTEM,
...
FROM registration r INNER JOIN
aplicativos a
on r.app_id = a.id
GROUP BY r.app_id ;
Does this give you the expected result?
SELECT
a.aplicativo as PROGRAMA,
COUNT(IF(DATE(r.created_at) = CURDATE(), 1, 0)) AS HOJE,
COUNT(IF(DATE(r.created_at) = DATE_SUB(CURDATE(), INTERVAL 1 DAY), 1, 0)) AS ONTEM,
COUNT(IF(DATE(r.created_at) = DATE_SUB(CURDATE(), INTERVAL 2 DAY), 1, 0)) AS 2DIAS,
COUNT(IF(DATE(r.created_at) = DATE_SUB(CURDATE(), INTERVAL 3 DAY), 1, 0)) AS 3DIAS,
COUNT(IF(DATE(r.created_at) = DATE_SUB(CURDATE(), INTERVAL 4 DAY), 1, 0)) AS 4DIAS,
COUNT(IF(DATE(r.created_at) = DATE_SUB(CURDATE(), INTERVAL 5 DAY), 1, 0)) AS 5DIAS
FROM registration r
INNER JOIN aplicativos a
ON r.app_id = a.id
GROUP BY r.app_id, DATE(r.created_at) with ROLLUP;

mysql group by day with count multi types of records

i have a table with id | type | publishedon
type may be 1,2,3 or 4 (int) value
i want to select posts for every day
now i'm using
SELECT FROM_UNIXTIME( `publishedon` , "%Y-%m-%d" ) AS `day` , count( id ) AS listings,
TYPE FROM posts
WHERE (
FROM_UNIXTIME( publishedon ) >= SUBDATE( NOW( ) , 30 )
)
GROUP BY `day`
the result
day listings
2013-09-02 17
2013-09-05 105
i want make listings filed more detailed like
day type_1 type_2 type_3 type_4
2013-09-02 10 4 6 3
2013-09-05 6 4 1 3
You simply need to put all your type values:
SELECT
FROM_UNIXTIME( `publishedon` , "%Y-%m-%d" ) AS `day`,
count(id) AS listings,
(SELECT COUNT(id) FROM `posts` WHERE `type`=1 AND FROM_UNIXTIME(`publishedon`, "%Y-%m-%d")=`day`) AS `type_1`,
(SELECT COUNT(id) FROM `posts` WHERE `type`=2 AND FROM_UNIXTIME(`publishedon`, "%Y-%m-%d")=`day`) AS `type_2`,
(SELECT COUNT(id) FROM `posts` WHERE `type`=3 AND FROM_UNIXTIME(`publishedon`, "%Y-%m-%d")=`day`) AS `type_3`,
(SELECT COUNT(id) FROM `posts` WHERE `type`=4 AND FROM_UNIXTIME(`publishedon`, "%Y-%m-%d")=`day`) AS `type_4`
FROM
`posts`
WHERE
FROM_UNIXTIME(`publishedon`) >= SUBDATE(NOW(), 30)
GROUP BY
`day`
but in fact, that will work slow since there are functions in conditions. If it is only a formatting matter, it's better to act like:
SELECT
FROM_UNIXTIME(`publishedon`, "%Y-%m-%d" ) AS `day`,
`type`,
count( id ) AS listings,
FROM
`posts`
WHERE
-- this should be better evaluated in application
-- since will not produce index using too:
FROM_UNIXTIME(`publishedon`) >= SUBDATE(NOW(), 30)
GROUP BY
`day`,
`type`
and then create desired formatting inside application.

count of sum with group by [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calculate a running total in MySQL
I need to get the sum of counts which is grouped for each of the dates.Now I am running the following query and getting the out put as follows :
SELECT `timestamp` , COUNT( * )
FROM `A`
WHERE `timestamp` >= '2013-01-04 07:12:12'
GROUP BY DATE_FORMAT( `timestamp` , '%Y-%m-%d' )
and I am getting
OUTPUT:
timestamp count(*)
-------------------------------------------------- -----------
2013-01-04 07:58:21 4
2013-01-05 09:28:56 38
2013-01-06 00:03:04 10
Now what I need is, I need to get the total sum of the counts grouped by date. That is for the second date it should be 42 and for third date it should be 52. How can I do this in a query?
Give it a try:
SELECT `timestamp` , #sum:= ifnull(#sum, 0 ) + COUNT( * )
FROM `A`
WHERE `timestamp` >= '2013-01-04 07:12:12'
GROUP BY DATE_FORMAT( `timestamp` , '%Y-%m-%d' )
Try :
SELECT
timestamp t ,
(select count(*) from A where timestamp <= t)
FROM A
GROUP BY timestamp
ORDER BY timestamp
Can you try below SQL
SELECT DATE_FORMAT( ts_date , '%Y-%m-%d' ) as ts_dt_out, SUM(cnt)
FROM
(
SELECT `timestamp` ts_date , COUNT( * ) as cnt
FROM `A`
WHERE `timestamp` >= '2013-01-04 07:12:12'
GROUP BY DATE_FORMAT( `timestamp` , '%Y-%m-%d' )
)
as inner
WHERE ts_date >= '2013-01-04 07:12:12'
GROUP BY ts_dt_out
Note: Not tested let me know if it does not work
Here is a simple way
SELECT
`timestamp` ,
COUNT( * )
FROM `A`
WHERE `timestamp` >= '2013-01-04 07:12:12'
GROUP BY DATE(`timestamp`)