2014-03-04 23 views
0

尝试搜索类似的东西,但目前为止没有运气。带自定义值的MySQL GROUP BY

我有一个查询在包含电话日志(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) 

回答

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

换句话说,使用条件聚集和每个值在单独的列。

+0

谢谢你的代码中找到另一种方式来做到这一点。我原本只是花了一年又一个月,后来又增加了一天(似乎我昨天太困了,不想记住'DATE'函数),但它仍然给了我一个字符串的日期,而不是一个数字。 除此之外,它的工作原理与它应该完全一样,并且是一个整洁的方式。谢谢 :) – NorthBridge

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