views:

197

answers:

2

I need to be able to display data that I have in 15 minute increments in different display types. I have two queries that are giving me trouble. One shows data by half an hour, the other shows data by hour. The only issue is that the data totals change between queries. It's not counting the data that happens between the time frames, only AT the time frames.

Ex: There are 5 things that happen at 7:15am. 2 that happen at 7:30am and 4 that show at 7:00am.

The 15 minute view displays all of the data. The half hour view displays the data from 7:00am and from 7:30am but ignores the 7:15am.
The hour display only shows the 7:00am data

Here are my queries:

$query="SELECT * FROM data WHERE startDate='$startDate' and queue='$queue' GROUP BY HOUR(start),floor(minute(start)/30)";

and

$query="SELECT * FROM data WHERE startDate='$startDate' and queue='$queue' GROUP BY HOUR(start) ";

How can I pull out the data in groups like I have but get all the data included?

Is the issue the way the data is stored in the mysql table? Currently I have a column with dates (2010-03-29) and a column with times (00:00) Do I need to convert these into something else?

+1  A: 

The GROUP BY is wrong and you don't use any aggregate function in your query. Drop the GROUP BY, the database now has to guess what records it should select. And database should not guess, they have to get the correct answer and only the correct answer.

Change the SQL MODE and create a correct query.

Frank Heikens
So you're stating I'm going about the solution wrong? I get close to what I want but not exactly. Can you point me in the correct direction as to how I should be querying my database to group the records by half hour and hour increments?
stogdilla
+2  A: 

You're interpreting the 'group by' wrong. You don't "group" multiple records so you can get them all with a single fetchrow() call. What happens is the database will collapse all records matching the group-by clauses into a single record. Take a simple game score table:

id   playername  score
----------------------
1    John        23
2    Fred        12
3    Jack        9
4    John        18

If you did the following query: SELECT id, playername, score FROM table GROUP BY playername, you'd get the following result set:

id   playername  score
----------------------
1    John        23
2    Fred        12
3    Jack        9

Hey! Where did John #4 go? He's vanished, because the row with id#4 matched the GROUP BY clause and has been collapsed into the first row that was found to match (#1). Not very useful by itself, you've now lost all the data associated with id #4. But this is where the aggregate functions (sum, count, average, etc...) come into play: SELECT id, playername, SUM(score) FROM table GROUP BY playername:

id   playername  score
----------------------
1    John        41   <---notice the change (23 + 18 = 41)
2    Fred        12
3    Jack        9

With your queries, you've got two choices:

  1. Leave the GROUP BY as-is, and do whatever calculations you want on the grouped data within the query (summing, counting, averaging, etc...) so that you get aggregate results for each of the matching time periods
  2. Remove the GROUP BY clauses, perform whatever calculations you want in your application
  3. Convert the GROUP BY clauses into result fields in the query, so you can process per-period in your code based on these new columns: SELECT *, HOUR(start), FLOOR(MINUTE(start)/30) FROM data
Marc B
Went with Option one. Thanks for your help. Made WAY more sense, I felt dumb but when it worked exactly how I wanted it to the dumb feeling faded. Thanks so much!
stogdilla