SQL Server子查询/连接计数基于值

时间:2016-02-24 10:12:16

标签: sql sql-server join subquery

请帮助我:

我在表格中有以下数据:

Menu                    dateTime                  CLI

START                   2016-02-23 14:08:52.047   4001
WELCOME                 2016-02-23 14:08:52.047   4001
LANG_SEL                2016-02-23 14:08:52.047   4001
SERVICE_MENU            2016-02-23 14:08:52.047   4001
CUSTOMER_ACCOUNT        2016-02-23 14:08:52.047   4001
BILLING_MENU            2016-02-23 14:08:52.047   4001
STOP                    2016-02-23 14:08:52.047   4001
START                   2016-02-23 14:08:52.047   2000
WELCOME                 2016-02-23 14:08:52.047   2000
LANG_SEL                2016-02-23 14:08:52.047   2000
BILLING_MENU            2016-02-23 14:08:52.047   2000
STOP                    2016-02-23 14:08:52.047   2000
START                   2016-02-23 14:08:52.047   34543
WELCOME                 2016-02-23 14:08:52.047   34543
LANG_SEL                2016-02-23 14:08:52.047   34543
SERVICE_MENU            2016-02-23 14:08:52.047   34543
BillComplaintSelection  2016-02-23 14:08:52.047   34543
VerbalizeBilltkt        2016-02-23 14:08:52.047   34543
STOP                    2016-02-23 14:08:52.047   34543
START                   2016-02-23 14:08:52.047   4001
WELCOME                 2016-02-23 14:08:52.047   4001
LANG_SEL                2016-02-23 14:08:52.047   4001
BILLING_MENU            2016-02-23 14:08:52.047   4001
VerbalizebillDetails    2016-02-23 14:08:52.047   4001
BILLING_MENU            2016-02-23 14:08:52.047   4001
STOP                    2016-02-23 14:08:52.047   4001

我的会话以值 START 开头,结束时值停止我想在停止<之前计算菜单名称的出现次数/ strong>每天。

从上面的数据中我必须得到以下输出:

Menu                        Count     DateTime

BILLING_MENU                3        2016-02-23 14:08:52.047
VerbalizeBilltkt            1        2016-02-23 14:08:52.047

2 个答案:

答案 0 :(得分:2)

如果dateTime字段按升序包含离散日期时间值,则可以使用以下查询来确定每个START - STOP间隔的开始/结束时间:

SELECT t1.`dateTime` AS start_time,  
      (SELECT t2.`dateTime`
       FROM mytable AS t2
       WHERE t2.ID = 'STOP' AND t1.CLI = t2.CLI AND 
             t1.`dateTime` < t2.`dateTime`
       ORDER BY t2.`dateTime` ASC LIMIT 1) AS end_time
FROM mytable AS t1
WHERE t1.ID = 'START'

使用上述内容可以实现以下内容,以计算所有间隔中ID个出现次数:

SELECT ID, 
       SUM(CASE WHEN cnt >= 1 THEN 1 END) AS cnt,
       DATE(start_time)
FROM (       
  SELECT x1.ID, COUNT(*) AS cnt, x2.start_time
  FROM mytable AS x1
  INNER JOIN (
    SELECT t1.`dateTime` AS start_time,  
          (SELECT t2.`dateTime`
           FROM mytable AS t2
           WHERE t2.ID = 'STOP' AND
                 t1.CLI = t2.CLI AND 
                 t1.`dateTime` < t2.`dateTime`
           ORDER BY t2.`dateTime` ASC LIMIT 1) AS end_time
    FROM mytable AS t1
    WHERE t1.ID = 'START'
  ) AS x2 ON x1.`dateTime` BETWEEN x2.start_time AND x2.end_time
  WHERE x1.ID <> 'START' AND x1.ID <> 'STOP' AND x1.ID <> 'WELCOME'
  GROUP BY ID, x2.start_time, x2.end_time) AS t
GROUP BY ID, DATE(start_time)

Demo here

修改

如果您只想计算在每个STOP记录之前发生的记录,那么您可以使用以下查询:

SELECT DATE(`dateTime`), ID, COUNT(*)
FROM (
  SELECT t1.`dateTime`, 
        (SELECT ID
         FROM mytable AS t2
         WHERE t1.CLI = t2.CLI AND 
               t2.`dateTime` < t1.`dateTime`
         ORDER BY t2.`dateTime` DESC LIMIT 1) AS ID      
  FROM mytable AS t1
  WHERE ID = 'STOP') AS t
  GROUP BY DATE(`dateTime`), ID

Demo here

答案 1 :(得分:-1)

这可以回答你的问题...

SELECT ID, COUNT(ID) AS TotalCount, -- You cannot use count as a field name CAST(DateTime AS DATE) AS DateOnly FROM TableName WHERE ID <> 'Start' or ID <> 'Stop' GROUP BY ID, CAST(DateTime AS DATE)