views:

70

answers:

4

This is my current query

SELECT DAYNAME(date_created) AS Day, 
COUNT(*) AS my_count FROM sometable 
WHERE (@date_created >= '2010-10-20 21:02:38' OR @date_created IS NULL) 
AND (@date_created <= '2010-10-27 21:02:38' OR @date_created IS NULL) 
GROUP BY DAY(date_created)

It only returns data for that day if the count exists.

I was mucking around with ifnull, but no luck

Im sure this is an easy one, but i can't figure it out!

Any help would be so appreciated

A: 

MySQL lacks a way to generate a recordset in runtime (like generate_series in PostgreSQL).

The only way to do this query is to keep around a table of all possible dates (or, better, a smaller table you can cross-join with itself):

CREATE TABLE a (a INT PRIMARY KEY);

INSERT
INTO    a
VALUES
        (0),
        (1),
        …
        (99)

Then you can generate a list of all possible dates and left join your table with it:

SLEECT  '2010-01-01' + INTERVAL 10000 * a1.a + 100 * a2.a + a3.a DAY AS dt,
        COUNT(date_created)
FROM    a a1
CROSS JOIN
        a a2
CROSS JOIN
        a a3
LEFT JOIN
        sometable
ON      date_created = '2010-01-01' + INTERVAL 10000 * a1.a + 100 * a2.a + a3.a DAY
WHERE   (a1.a, a2.a, a3.a) <= (0, 3, 65)
GROUP BY
        dt

This condition:

(a1.a, a2.a, a3.a) <= (0, 3, 65)

means "take 365 records".

Quassnoi
im sure thats a good solution, but thats a bit over my head at the moment
Doug
@Quassnoi - would you not have a single table with values 0-99, and just introduce it with 3 aliases in the query? Or does MySQL not support table aliases?
Damien_The_Unbeliever
@Damien: yes, you can. It's just a rewrite from actual solution using separate tables for `years`, `month` and `days` (which wouldn't work without `ALLOW_INVALID_DATES`). Nice point.
Quassnoi
A: 

Welcome Doug! I ran a modified version of your SQL locally and I'm getting results even for those NULL dates. First things first - to real-time convert a null into some other value ("convert null to 0") you need to use the MySQL statement IF, if you know anything of Oracle, it's a lot like the DECODE command. A NULL value automatically evaluates to false, so you can simply write:

SELECT IF(date_created,date_created,0) FROM sometable

Of course... 0 isn't anymore a date then NULL is. I found the DAYNAME function simply passes on NULL dates for you to deal with:

SELECT DAYNAME(date_created) day,COUNT(*) my_count 
FROM sometable
WHERE date_created IS NULL OR
 (date_created>='2010-10-20 21:02:38' AND date_created <= '2010-10-27 21:02:38')
GROUP BY DAY(date_created)

What I'm getting out of that (with an example data set) is 8 values of day: 7 days of the week + NULL (with a count). Which kinda makes sense... you can't convert an unknown date into a day of the week.

It could have been your errant @ signs in your SQL, unless I'm misunderstanding your purpose.

UPDATE

Based on your last comment, you need to take over processing in PHP. Build the days array before hand, then add the MySQL data to your existing array so that all the days are there (and in order).

Source: day-counting in PHP

//You may not even need "date_created IS NULL OR" in the where statement
$sql="SELECT DAYNAME(date_created) day,COUNT(*) my_count 
    FROM sometable
    WHERE date_created IS NULL OR
     (date_created>='2010-10-20 21:02:38' 
      AND date_created <= '2010-10-27 21:02:38')
    GROUP BY DAY(date_created)";
//We're assuming you've setup a MySQL connection in $conn
$result = @mysql_query($sql, $conn) or die(mysql_error());

//Starting data - Zero for every day
$days=array("Sunday"=>0,"Monday"=>0,"Tuesday"=>0,"Wednesday"=>0,
   "Thursday"=>0,"Friday"=>0,"Saturday"=>0);
while($row = mysql_fetch_array($result)) {
   $days[$row["day"]]+=$row["my_count"];
}
mysql_free_result($result);

//Preview the output
print_r($days);
Rudu
awsome thanks, ill check it out
Doug
hmm so are you saying its impossible ?? .... i may need to do something funky with php to fill the gaps somehow
Doug
i guess in a way, im asking mysql to invent data... which isn't really part of fetching and manipulating... is it?
Doug
With the IF statement you can tell MySQL what data to use instead of null `SELECT IF(date_created,date_created,now()) FROM sometable` which is sorta like creating. It's not impossible, but based on the example you gave I can't see why you'd want to do this - if there's no `date_created` how can you count that as being created on some day of the week? {The above will end up skewing your numbers for whatever day you run the statement} As you say, you can also use PHP to figure out what to do with those NULL values.
Rudu
basically i am showing stats which show impressions on a daily basis. At the moment, it looks and works fine as long as there is data. But if on one day there are no impressions, its skipped all together.
Doug
A: 

The @ sign describes a user variable - are you pulling date_created from sometable? If so, remove the @ sign from the variables.

Not sure why you would want to include date_created if it's null. Maybe some sample rows and desired output would help in illustrating exactl what you're looking for. Good luck! :)

ajacian81