是否可以使用mysql通过单个查询选择多个重叠的日期范围?

时间:2012-02-01 01:37:28

标签: mysql select date-range

我目前有一个有点大的SQL语句,每次UNIONs使用相同的SELECT语句3次,日期范围更大。 IE过去30天,过去90天和过去180天。 SQL工作得很好,我甚至可以确定查询需要花费很长时间才能运行,我只是想知道是否还有一个SELECT语句做同样的事情。

看到有几个人要求查看我的代码: -

SELECT mdt_userid AS logging_officer,
    'Last 30 Days' AS timespan,
    ACD_Time,
    TRUNCATE (( 1 - ( (TotalAssisting+TotalBRB+TotalShift+TotalLunch+TotalBreak-IF(TotalLunch<(DaysLoggedIn*Lunch),TotalLunch,(DaysLoggedIn*Lunch))-IF((TotalBRB+TotalBreak)<(DaysLoggedIn*1800),(TotalBRB+TotalBreak),(DaysLoggedIn*1800))) / (TotalLoginTime-TotalEreq-TotalDefault) ) ) *100,2) AS Utilization_percent,
    TRUNCATE((GRS_total/calls)*100,1) AS Ratio,
    IF (TotalACW =0,0,TotalACW / calls) AS ACW,
    grs.percent AS percent,
    TRUNCATE (((grs_total - wo_ci) / grs_total) *100,2) AS percent_w_ci,
    TRUNCATE (calls / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS call_per_hour,
    TRUNCATE (GRS_total / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS grs_per_hour 
FROM (SELECT DISTINCT fullname,
            SUM( IF (ReasonCode =  '138',  `ReasonCodeDuration` , 0) ) AS TotalAssisting,
            SUM( IF (ReasonCode =  '146',  `ReasonCodeDuration` , 0) ) AS TotalBRB,
            SUM( IF (ReasonCode =  '143',  `ReasonCodeDuration` , 0) ) AS TotalShift,
            SUM( IF (ReasonCode =  '141',  `ReasonCodeDuration` , 0) ) AS TotalACW,
            SUM( IF (ReasonCode =  '231',  `ReasonCodeDuration` , 0) ) AS TotalEreq,
            SUM( IF (ReasonCode =  '0',  `ReasonCodeDuration` , 0) ) AS TotalDefault,
            COUNT(ReasonCode = '136') AS CountLunch,
            SUM( IF (ReasonCode =  '136',  `ReasonCodeDuration` , 0) ) AS TotalLunch,
            SUM( IF (ReasonCode =  '137',  `ReasonCodeDuration` , 0) ) AS TotalBreak,
            SUM(  `ReasonCodeDuration` ) AS NRduration
        FROM  `CiscoAgentNotready` 
        WHERE StartDate >= '".adjustdate($DateTo,0,0,-30)." 00:00:00' 
                AND StartDate <= '".$DateTo." 23:59:59'
        GROUP BY fullname)
        AS notready, 
    (SELECT DISTINCT agentname,
            SUM( loginduration ) AS TotalLoginTime, COUNT(Date(logondate)) as DaysLoggedIn
        FROM CiscoAgentLogintime
        WHERE logondate  >= '".adjustdate($DateTo,0,0,-30)." 00:00:00' 
                AND logondate  <= '".$DateTo." 23:59:59'
        GROUP BY agentname)
        AS logintime, 
    (SELECT DISTINCT full_name, 
            SUM( handled ) AS calls
        FROM  `CiscoAgentCalls` 
        WHERE DateCol   >= '".adjustdate($DateTo,0,0,-30)."'  
                AND DateCol   <= '".$DateTo."'
        GROUP BY full_name)
        AS calls, 
    (SELECT DISTINCT logging_officer, 
            SUM( first_call ) AS firstcall, 
            SUM(IF (Config_item =  'unknown', 1, 0) ) AS wo_ci,
            COUNT( * ) AS GRS_total, 
            TRUNCATE ((SUM( first_call ) / COUNT( * )) *100,2) AS percent
        FROM (SELECT logging_officer, 
                IF (logging_officer =  `Resolving_Officer` , 1, 0) AS first_call, 
                Config_item
            FROM  `callcentergrsdata` 
            WHERE log_Date >= '".adjustdate($DateTo,0,0,-30)." 00:00:00' 
                 AND log_Date <= '".$DateTo." 23:59:59') 
            AS a
        GROUP BY logging_officer) 
        AS grs,
    (SELECT DISTINCT agtName,
            SUM(TalkTime) as sumTalk,
            SUM(CallsHandled) as answered,
            SUM(TalkTime)/SUM(CallsHandled) as ACD_Time
        FROM (SELECT CONCAT( LastName,  ', ', FirstName ) AS agtName,
                TalkTime, 
                CallsHandled
            FROM `CiscoAgentAHT`
            WHERE DateCol   >= '".adjustdate($DateTo,0,0,-30)."'  
                AND DateCol   <= '".$DateTo."') as subAHT
        GROUP BY agtName) 
        AS AHT,
    techjtblnew
WHERE mdt_userid = '".$user."'
AND notready.fullname = logintime.agentname
AND calls.full_name = notready.fullname 
AND calls.full_name = AHT.agtName
AND techjtblnew.cisco = notready.fullname 
AND grs.logging_officer = techjtblnew.grs
UNION 
SELECT mdt_userid AS logging_officer,
    'Last 90 Days' AS timespan,
    ACD_Time,
    TRUNCATE (( 1 - ( (TotalAssisting+TotalBRB+TotalShift+TotalLunch+TotalBreak-IF(TotalLunch<(DaysLoggedIn*Lunch),TotalLunch,(DaysLoggedIn*Lunch))-IF((TotalBRB+TotalBreak)<(DaysLoggedIn*1800),(TotalBRB+TotalBreak),(DaysLoggedIn*1800))) / (TotalLoginTime-TotalEreq-TotalDefault) ) ) *100,2) AS Utilization_percent,
    TRUNCATE((GRS_total/calls)*100,1) AS Ratio,
    IF (TotalACW =0,0,TotalACW / calls) AS ACW,
    grs.percent AS percent,
    TRUNCATE (((grs_total - wo_ci) / grs_total) *100,2) AS percent_w_ci,
    TRUNCATE (calls / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS call_per_hour,
    TRUNCATE (GRS_total / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS grs_per_hour 
FROM (SELECT DISTINCT fullname,
            SUM( IF (ReasonCode =  '138',  `ReasonCodeDuration` , 0) ) AS TotalAssisting,
            SUM( IF (ReasonCode =  '146',  `ReasonCodeDuration` , 0) ) AS TotalBRB,
            SUM( IF (ReasonCode =  '143',  `ReasonCodeDuration` , 0) ) AS TotalShift,
            SUM( IF (ReasonCode =  '141',  `ReasonCodeDuration` , 0) ) AS TotalACW,
            SUM( IF (ReasonCode =  '231',  `ReasonCodeDuration` , 0) ) AS TotalEreq,
            SUM( IF (ReasonCode =  '0',  `ReasonCodeDuration` , 0) ) AS TotalDefault,
            COUNT(ReasonCode = '136') AS CountLunch,
            SUM( IF (ReasonCode =  '136',  `ReasonCodeDuration` , 0) ) AS TotalLunch,
            SUM( IF (ReasonCode =  '137',  `ReasonCodeDuration` , 0) ) AS TotalBreak,
            SUM(  `ReasonCodeDuration` ) AS NRduration
        FROM  `CiscoAgentNotready` 
        WHERE StartDate >= '".adjustdate($DateTo,0,0,-90)." 00:00:00' 
                AND StartDate <= '".$DateTo." 23:59:59'
        GROUP BY fullname)
        AS notready, 
    (SELECT DISTINCT agentname,
            SUM( loginduration ) AS TotalLoginTime, COUNT(Date(logondate)) as DaysLoggedIn
        FROM CiscoAgentLogintime
        WHERE logondate  >= '".adjustdate($DateTo,0,0,-90)." 00:00:00' 
                AND logondate  <= '".$DateTo." 23:59:59'
        GROUP BY agentname)
        AS logintime, 
    (SELECT DISTINCT full_name, 
            SUM( handled ) AS calls
        FROM  `CiscoAgentCalls` 
        WHERE DateCol   >= '".adjustdate($DateTo,0,0,-90)."'  
                AND DateCol   <= '".$DateTo."'
        GROUP BY full_name)
        AS calls, 
    (SELECT DISTINCT logging_officer, 
            SUM( first_call ) AS firstcall, 
            SUM(IF (Config_item =  'unknown', 1, 0) ) AS wo_ci,
            COUNT( * ) AS GRS_total, 
            TRUNCATE ((SUM( first_call ) / COUNT( * )) *100,2) AS percent
        FROM (SELECT logging_officer, 
                IF (logging_officer =  `Resolving_Officer` , 1, 0) AS first_call, 
                Config_item
            FROM  `callcentergrsdata` 
            WHERE log_Date >= '".adjustdate($DateTo,0,0,-90)." 00:00:00' 
                 AND log_Date <= '".$DateTo." 23:59:59') 
            AS a
        GROUP BY logging_officer) 
        AS grs,
    (SELECT DISTINCT agtName,
            SUM(TalkTime) as sumTalk,
            SUM(CallsHandled) as answered,
            SUM(TalkTime)/SUM(CallsHandled) as ACD_Time
        FROM (SELECT CONCAT( LastName,  ', ', FirstName ) AS agtName,
                TalkTime, 
                CallsHandled
            FROM `CiscoAgentAHT`
            WHERE DateCol   >= '".adjustdate($DateTo,0,0,-90)."'  
                AND DateCol   <= '".$DateTo."') as subAHT
        GROUP BY agtName) 
        AS AHT,
    techjtblnew
WHERE mdt_userid = '".$user."'
AND notready.fullname = logintime.agentname
AND calls.full_name = notready.fullname 
AND calls.full_name = AHT.agtName
AND techjtblnew.cisco = notready.fullname 
AND grs.logging_officer = techjtblnew.grs
UNION 
SELECT mdt_userid AS logging_officer,
    'Last 120 Days' AS timespan,
    ACD_Time,
    TRUNCATE (( 1 - ( (TotalAssisting+TotalBRB+TotalShift+TotalLunch+TotalBreak-IF(TotalLunch<(DaysLoggedIn*Lunch),TotalLunch,(DaysLoggedIn*Lunch))-IF((TotalBRB+TotalBreak)<(DaysLoggedIn*1800),(TotalBRB+TotalBreak),(DaysLoggedIn*1800))) / (TotalLoginTime-TotalEreq-TotalDefault) ) ) *100,2) AS Utilization_percent,
    TRUNCATE((GRS_total/calls)*100,1) AS Ratio,
    IF (TotalACW =0,0,TotalACW / calls) AS ACW,
    grs.percent AS percent,
    TRUNCATE (((grs_total - wo_ci) / grs_total) *100,2) AS percent_w_ci,
    TRUNCATE (calls / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS call_per_hour,
    TRUNCATE (GRS_total / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS grs_per_hour 
FROM (SELECT DISTINCT fullname,
            SUM( IF (ReasonCode =  '138',  `ReasonCodeDuration` , 0) ) AS TotalAssisting,
            SUM( IF (ReasonCode =  '146',  `ReasonCodeDuration` , 0) ) AS TotalBRB,
            SUM( IF (ReasonCode =  '143',  `ReasonCodeDuration` , 0) ) AS TotalShift,
            SUM( IF (ReasonCode =  '141',  `ReasonCodeDuration` , 0) ) AS TotalACW,
            SUM( IF (ReasonCode =  '231',  `ReasonCodeDuration` , 0) ) AS TotalEreq,
            SUM( IF (ReasonCode =  '0',  `ReasonCodeDuration` , 0) ) AS TotalDefault,
            COUNT(ReasonCode = '136') AS CountLunch,
            SUM( IF (ReasonCode =  '136',  `ReasonCodeDuration` , 0) ) AS TotalLunch,
            SUM( IF (ReasonCode =  '137',  `ReasonCodeDuration` , 0) ) AS TotalBreak,
            SUM(  `ReasonCodeDuration` ) AS NRduration
        FROM  `CiscoAgentNotready` 
        WHERE StartDate >= '".adjustdate($DateTo,0,0,-120)." 00:00:00' 
                AND StartDate <= '".$DateTo." 23:59:59'
        GROUP BY fullname)
        AS notready, 
    (SELECT DISTINCT agentname,
            SUM( loginduration ) AS TotalLoginTime, COUNT(Date(logondate)) as DaysLoggedIn
        FROM CiscoAgentLogintime
        WHERE logondate  >= '".adjustdate($DateTo,0,0,-120)." 00:00:00' 
                AND logondate  <= '".$DateTo." 23:59:59'
        GROUP BY agentname)
        AS logintime, 
    (SELECT DISTINCT full_name, 
            SUM( handled ) AS calls
        FROM  `CiscoAgentCalls` 
        WHERE DateCol   >= '".adjustdate($DateTo,0,0,-120)."'  
                AND DateCol   <= '".$DateTo."'
        GROUP BY full_name)
        AS calls, 
    (SELECT DISTINCT logging_officer, 
            SUM( first_call ) AS firstcall, 
            SUM(IF (Config_item =  'unknown', 1, 0) ) AS wo_ci,
            COUNT( * ) AS GRS_total, 
            TRUNCATE ((SUM( first_call ) / COUNT( * )) *100,2) AS percent
        FROM (SELECT logging_officer, 
                IF (logging_officer =  `Resolving_Officer` , 1, 0) AS first_call, 
                Config_item
            FROM  `callcentergrsdata` 
            WHERE log_Date >= '".adjustdate($DateTo,0,0,-120)." 00:00:00' 
                 AND log_Date <= '".$DateTo." 23:59:59') 
            AS a
        GROUP BY logging_officer) 
        AS grs,
    (SELECT DISTINCT agtName,
            SUM(TalkTime) as sumTalk,
            SUM(CallsHandled) as answered,
            SUM(TalkTime)/SUM(CallsHandled) as ACD_Time
        FROM (SELECT CONCAT( LastName,  ', ', FirstName ) AS agtName,
                TalkTime, 
                CallsHandled
            FROM `CiscoAgentAHT`
            WHERE DateCol   >= '".adjustdate($DateTo,0,0,-120)."'  
                AND DateCol   <= '".$DateTo."') as subAHT
        GROUP BY agtName) 
        AS AHT,
    techjtblnew
WHERE mdt_userid = '".$user."'
AND notready.fullname = logintime.agentname
AND calls.full_name = notready.fullname 
AND calls.full_name = AHT.agtName
AND techjtblnew.cisco = notready.fullname 
AND grs.logging_officer = techjtblnew.grs

2 个答案:

答案 0 :(得分:0)

是。只需查询最近180天并在软件层中解析它。

如果您想要指示每行中哪一行,您可以使用CASEIF语句:

http://dev.mysql.com/doc/refman/5.0/en/if-statement.html

IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list] ...
    [ELSE statement_list]
END IF

http://dev.mysql.com/doc/refman/5.0/en/case-statement.html

CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list] ...
    [ELSE statement_list]
END CASE

<强>更新

好的,既然我知道你的目的是什么,我可以提供一个更合适的解决方案,我相信它会满足你的需求。

如果您提前UNION为各种时间跨度添加列,我认为没有办法解决UNION 但是你可以只查询一次结果。

在此示例中,我在span期间创建了一个名为UNION的列。 t1是生成的“表格”。由于每个日期范围的span不同,因此行会多次显示。

示例表:

mysql> select * from test;
+----+------------+
| id | when       |
+----+------------+
|  1 | 2012-02-01 |
|  2 | 2012-01-01 |
|  3 | 2011-09-01 |
+----+------------+

使用工会查询:

mysql> 
    ->    SELECT *, 1 as 'span' FROM `test` WHERE `when` > '2012-01-15'
    -> UNION
    ->    SELECT *, 2 as 'span' FROM `test` WHERE `when` > '2011-12-15'
    -> UNION
    ->    SELECT *, 3 as 'span' FROM `test` WHERE `when` > '2011-08-15';

+----+------------+------+
| id | when       | span |
+----+------------+------+
|  1 | 2012-02-01 |    1 |
|  2 | 2012-01-01 |    2 |
|  1 | 2012-02-01 |    2 |
|  3 | 2011-09-01 |    3 |
|  2 | 2012-01-01 |    3 |
|  1 | 2012-02-01 |    3 |
+----+------------+------+

使用该联盟查询(自定义SELECTWHERE t1.id > 0):

mysql> 
    -> SELECT
    ->    `id`,
    ->    `when`,
    ->    if(`span` = 1, 'Last 30 Days',
    ->       if(`span` = 2, 'Last 60 Days',
    ->          'Last 180 Days')) as 'Timespan'
    -> FROM (
    ->       SELECT *, 1 as 'span' FROM `test` WHERE `when` > '2012-01-15'
    ->    UNION
    ->       SELECT *, 2 as 'span' FROM `test` WHERE `when` > '2011-12-15'
    ->    UNION
    ->       SELECT *, 3 as 'span' FROM `test` WHERE `when` > '2011-08-15'
    -> ) as t1
    -> WHERE t1.id > 0;

+----+------------+---------------+
| id | when       | Timespan      |
+----+------------+---------------+
|  1 | 2012-02-01 | Last 30 Days  |
|  2 | 2012-01-01 | Last 60 Days  |
|  1 | 2012-02-01 | Last 60 Days  |
|  3 | 2011-09-01 | Last 180 Days |
|  2 | 2012-01-01 | Last 180 Days |
|  1 | 2012-02-01 | Last 180 Days |
+----+------------+---------------+

您将从t1开始执行所有查询内容,而不是从表本身开始。在创建t1时添加额外的列允许每行多次出现,因为额外的行将使其唯一。

答案 1 :(得分:0)

似乎你可以逃脱复杂的分组。例如,这是使用记录执行此操作的通用方法:

SELECT
  count(*),
  MIN(creation)
FROM record
WHERE creation > CURDATE() - INTERVAL 120 DAY
GROUP BY 
 IF(creation>CURDATE() - INTERVAL 30 DAY,'030',
   IF(creation>CURDATE() - INTERVAL 90 DAY,'090',
     IF(creation>CURDATE() - INTERVAL 120 DAY,'120',
       'OLDER'
     )
   )
 )

您可能希望随时添加记录,因为每个范围都是独占的。

以下是示例输出:

+----------+---------------+
| count(*) | MIN(creation) |
+----------+---------------+
|     1472 | 2012-01-08    |
|     2336 | 2011-11-09    |
|     1528 | 2011-10-10    |
|     5336 | 2011-10-10    |
+----------+---------------+
4 rows in set (0.13 sec)