带有自定义值的MySQL GROUP BY

时间:2014-03-04 15:54:41

标签: mysql sql

试图寻找类似的东西,但到目前为止没有运气。

我在包含电话日志(ID,号码,来源和电话名称)的表上执行查询。其目的是获取在电话名称上按不同标准分组的呼叫总数(有四个或五个不同的标准)。目前我正在做这样的事情:

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)
;

问题,正如您可能已经看到的那样,对于每个LIKE / NOT LIKE标准,我必须使用不同的标准构建另一个查询,我想这很快就会变得讨厌(目前有5个查询,在返回结果之前总共运行20秒。)

所以我想知道,是不是有一些简单的方法来避免多个查询并通过构建这样的自定义分组来实现这一点:

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)

2 个答案:

答案 0 :(得分:1)

首先,group by子句的日期部分没有意义。我假设你只想要date(calldate)。但是,您今天(2014-03-04)生成以下值:

2014 + '-' + 03 + '-' + 04

MySQL使用'+'添加数字。它会根据前导数字字符自动将字符串转换为数字,如果没有,则值为0。在MySQL中,表达式总计为:2021。对我来说,这似乎是一件奇怪的事情。

我怀疑你想要这样的东西:

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);

换句话说,使用条件聚合并将每个值放在一个单独的列中。

答案 1 :(得分:0)

只是为了记录,我发现了另一种使用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);