2

On a previous question a table could be created and populated with the days of the month, but I'd like that table to be populated slightly different: each day of the month should have three different hour intervals.

According to that question, this code by Tom Mac:

create table all_date 
(id int unsigned not null primary key auto_increment, 
a_date date not null,
last_modified timestamp not null default current_timestamp on update current_timestamp,
unique key `all_date_uidx1` (a_date));

And then,

DELIMITER //


CREATE PROCEDURE populate_all_dates(IN from_date DATE, IN days_into_future INT)

BEGIN

 DECLARE v_date DATE;
 DECLARE ix int;


 SET ix := 0;
 SET v_date := from_date;


 WHILE v_date <= (from_date + interval days_into_future day) DO

  insert into all_date (a_date) values (v_date) 
  on duplicate key update last_modified = now();

  set ix := ix +1;

  set v_date := from_date + interval ix day;

 END WHILE;

END//

DELIMITER ;

And then you can run:

call populate_all_dates('2011-10-01',30);

To populate all dates for October (or whatever month, change the values of the function)

With that I could run the following query

select day(a.a_date) as 'October',
IFNULL(t.a1,0) as 'Auth1',
IFNULL(t.a2,0) as 'Auth2',
IFNULL(t.a50,0) as 'Auth50'
from all_date a
LEFT OUTER JOIN
(
SELECT date(wp.post_date) as post_date,
sum(case when wp.post_author = '1' then 1 else 0 end) as a1,
sum(case when wp.post_author = '2' then 1 else 0 end) as a2,
sum(case when wp.post_author = '50' then 1 else 0 end) as a50,
count(*) as 'All Auths'
FROM wp_posts wp
WHERE  wp.post_type = 'post'
AND wp.post_date  between '2011-10-01' and '2011-10-31 23:59:59'
GROUP BY date(wp.post_date)
) t
ON a.a_date = t.post_date
where a.a_date between '2011-10-01' and '2011-10-31'
group by day(a.a_date);

And I would get a table with the number of posts in my WordPress blog by author and day, similar to this:

+---------+---------+-------+------+---------+
| October | Auth1   | Auth2 | Auth3|  Auth4  |
+---------+---------+-------+------+---------+
|       1 |       0 |     0 |    0 |       0 |
|       2 |       0 |     0 |    1 |       0 |
|       3 |       4 |     4 |    6 |       2 |
|       4 |       4 |     3 |    5 |       2 |
|       5 |       7 |     0 |    5 |       2 |
|       6 |       4 |     4 |    0 |       2 |
|       7 |       0 |     2 |    1 |       2 |
|       8 |       0 |     0 |    7 |       0 |
.....
etc

But what I'dlike to have is each day divided in three different rows, each one corresponding to the following time ranges:

00:00-14:30 14:31-18:15 18:16-23:59

So the table should show something like (for example, I don't know how each of the time ranges could be shown, so a good way should be day 1, time range 1 (1-1), etc).

+---------+---------+-------+------+---------+
| October | Auth1   | Auth2 | Auth3|  Auth4  |
+---------+---------+-------+------+---------+
|    1-1  |       0 |     0 |    0 |       0 |
|    1-2  |       0 |     0 |    0 |       0 |
|    1-3  |       0 |     0 |    0 |       0 |
|    2-1  |       0 |     0 |    1 |       0 |
|    2-2  |       0 |     0 |    0 |       0 |
|    2-3  |       0 |     0 |    0 |       0 |
|    3-1  |       1 |     2 |    3 |       0 |
|    3-2  |       1 |     2 |    2 |       2 |
|    3-3  |       2 |     0 |    1 |       0 |
etc...

As you can see, the three rows sum is equivalent to each of the previous unique row for the day.

Is that possible?

Community
  • 1
  • 1
javipas
  • 281
  • 1
  • 6
  • 16
  • I understand that doubt... you shouldn't just accept to grow the rate... BUT one of the 2 remaining not-accepted is worth to accept (http://stackoverflow.com/questions/4830261/i-want-an-auto-hard-refresh-not-a-simple-auto-refresh-on-my-webpages/6938551#6938551)... accept does not mean that you specifically used this solution but it also helps others looking for an answer to see which answer(s) are good ones – Yahia Oct 31 '11 at 10:12
  • Good point! I've accepted that answer as well, thanks for the tip Yahia ;) – javipas Oct 31 '11 at 11:05

1 Answers1

1

use (UPDATE #2)

SELECT 
a.a_datetm as 'October',
IFNULL(p.a1,0) as 'Auth1',
IFNULL(p.a2,0) as 'Auth2',
IFNULL(p.a50,0) as 'Auth50'
FROM
(
SELECT CONCAT (day(X.a_date), '-1') AS a_datetm
FROM all_date X
WHERE X.a_date between '2011-10-01' and '2011-10-31'
UNION ALL
SELECT CONCAT (day(Y.a_date), '-2') AS a_datetm
FROM all_date Y
WHERE Y.a_date between '2011-10-01' and '2011-10-31'
UNION ALL
SELECT CONCAT (day(Z.a_date), '-3') AS a_datetm
FROM all_date Z
WHERE Z.a_date between '2011-10-01' and '2011-10-31'
) a
LEFT OUTER JOIN
(
SELECT 
CONCAT (day(wp.post_date), (CASE WHEN (TIME(wp.post_date) < '14:31:00') THEN '-1' WHEN (TIME(wp.post_date) BETWEEN '14:31:00' AND '18:15:59') THEN '-2' ELSE '-3' END )) AS a_datetm,
sum(case when wp.post_author = '1' then 1 else 0 end) as a1,
sum(case when wp.post_author = '2' then 1 else 0 end) as a2,
sum(case when wp.post_author = '50' then 1 else 0 end) as a50,
count(*) as 'All Auths'
FROM wp_posts wp
WHERE  wp.post_type = 'post'
AND wp.post_date  between '2011-10-01' and '2011-10-31 23:59:59'
GROUP BY CONCAT (day(wp.post_date), (CASE WHEN (TIME(wp.post_date) < '14:31:00') THEN '-1' WHEN (TIME(wp.post_date) BETWEEN '14:31:00' AND '18:15:59') THEN '-2' ELSE '-3' END ))
) p
ON a.a_datetm = p.a_datetm
ORDER BY a.a_datetm ASC;
Yahia
  • 69,653
  • 9
  • 115
  • 144
  • Yahia, it shows this error: ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE) as 'October', IFNULL(t.a1,0) as 'Auth1', IFNULL(t.a2,0) as 'Auth2', IFNULL' at line 1 I've tried to detect the error, but can't find the solution :( – javipas Oct 31 '11 at 12:57
  • @javipas I don't have MySQL here but please try the above change (added some `(` and changed `END CASE` to `END`). – Yahia Oct 31 '11 at 13:07
  • Mmmm, now it works, but it shows the same as the original query. This is the output (screenshot easier, here http://imgur.com/mRfow): +---------+-------+-------+--------+ | October | Auth1 | Auth2 | Auth50 | +---------+-------+-------+--------+ | 1-1 | 0 | 0 | 0 | | 10-1 | 5 | 0 | 9 | | 11-1 | 1 | 0 | 10 | | 12-1 | 0 | 0 | 4 | ... It's not showing but the first time interval (no 1-2, 1-3, 2-2, 2-3, etc), and it's including all the posts in these time interval. So the counting is not working fine :( – javipas Oct 31 '11 at 13:45
  • @javipas as promised an updated query which finally does it :-) – Yahia Oct 31 '11 at 17:21
  • Hi Yahia, sorry, I was away... Shows the following: ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'sum(case when wp.post_author = '1' then 1 else 0 end) as a1, sum(case when wp.po' at line 1 ---- I've checked the parenthesis and all seems OK, don't know what's the problem :( – javipas Oct 31 '11 at 20:41
  • Fantastic!!! There's a semicolon missing at the end ("ORDER BY a.a_datetm ASC;"), but the code is finally working!! It's almost perfect, but it shows some rows without order because it considers that after 1-3 goes 10-1 and not 2-1 (image shows better, http://imgur.com/kj5gs). Anyway, fantastic, fantastic work Yahia. Real magic there! Thank you so much! – javipas Oct 31 '11 at 20:54