Reputation: 674
Tried to search for something similar, but no luck so far.
I have a query executed upon a table containing phones logs (ID, number, source and phone name). Its purpose is to fetch the total number of calls grouped by different criterias on the phone name (there are like four or five different ones). Currently I'm doing something like this:
SELECT COUNT(phones_statistics.id) AS number_of_calls, phones_statistics.calldate
FROM phones_statistics
INNER JOIN phones ON phones_statistics.phone_id = phones.id
WHERE phones.abbr NOT LIKE '@%'
GROUP BY
YEAR(phones_statistics.calldate)
+ '-'
+ MONTH(phones_statistics.calldate)
+ '-'
+ DAY(phones_statistics.calldate)
;
The problem, as you can probably already see, is that for each LIKE/NOT LIKE criteria, I have to build another query with the different criteria, and I guess this is going to become nasty soon (currently there are 5 queries, running for a total of 20 seconds before returning results).
So I wondered, isn't there some easy way to avoid multiple queries and do the trick by constructing a custom grouping like this:
SELECT
COUNT(phones_statistics.id) AS number_of_calls,
phones_statistics.calldate,
(something like a switch - 4 statements, 4 return values,
assigned to this field)
AS custom_field
...
rest of the query
...
GROUP BY custom_field,
YEAR(phones_statistics.calldate)
+ '-'
+ MONTH(phones_statistics.calldate)
+ '-'
+ DAY(phones_statistics.calldate)
Upvotes: 1
Views: 1838
Reputation: 674
Just for the record, I've found another way to do this by using CASE...WHEN
SELECT
COUNT(phones_statistics.id) AS calls_number,
DATE(phones_statistics.calldate),
CASE
WHEN phones.abbr LIKE '%pattern1%' THEN 'Result1'
WHEN phones.abbr LIKE '%pattern2%' THEN 'Result2'
ELSE 'default_result'
END
as type
FROM phones_statistics
INNER JOIN phones ON phones_statistics.phone_id = phones.id
GROUP BY type, DATE(phones_statistics.calldate);
Upvotes: 0
Reputation: 1271003
First, the date part of your group by
clause does not make sense. I assume that you simply want date(calldate)
. However, you are producing the following value for today (2014-03-04):
2014 + '-' + 03 + '-' + 04
MySQL uses the '+' for adding numbers. It automatically converts strings to numbers based on leading numeric characters, with the value being 0
if there are none. In MySQL, the expression adds up to: 2021
. To me, this seems like a strange thing to do.
I suspect you want something like this:
SELECT date(ps.calldate) as calldate,
SUM(ps.abbr NOT LIKE 'patten1%') as numPattern1,
SUM(ps.abbr NOT LIKE 'patten2%') as numPattern2,
SUM(ps.abbr NOT LIKE 'patten3%') as numPattern3,
SUM(ps.abbr NOT LIKE 'patten4%') as numPattern4,
SUM(ps.abbr NOT LIKE 'patten5%') as numPattern5
FROM phones_statistics ps INNER JOIN
phones p
ON ps.phone_id = p.id
WHERE ps.abbr NOT LIKE '@%'
GROUP BY date(calldate);
In other words, use conditional aggregation and put each value in a separate column.
Upvotes: 1