select语句中的嵌套查询,用于根据从外部查询派生的字段计数条目

时间:2014-07-15 17:57:08

标签: sql sql-server tsql

我正在努力解决一个在我看来应该可以实现的事情,但是我无法让它发挥作用......这里的情景:

我有两个表格结构如下:

1- table,每10分钟记录一次数据:(tab_cycle)

timestamp      | value1 | value2 ... | valueN
20140715 10:10 |   10   |   20   ... |   x
20140715 10:00 |   14   |   45   ... |   x

2 - 使用事件驱动结构(tab_event)记录数据的表

timestamp      | descr  |  value
20140715 10:09 |   a    |    10
20140715 10:04 |   a    |    14
20140715 10:00 |   a    |    11
20140715 09:59 |   a    |    10
20140715 09:54 |   a    |    20

现在我想实现(如果可能的话),而无需使用游标来创建一个会产生以下结果的select语句:

timestamp      | value1 | value2 ... | valueN |countEvent
20140715 10:10 |   10   |   20   ... |   x    |   null
20140715 10:00 |   14   |   45   ... |   x    |    3

所以基本上计算在时间戳和时间戳+ 10min内生成具有所选标签的所选事件的时间。

我尝试的是以下但没有取得多大成功:

SELECT tab_cycle.timestamp AS startTime, DATEADD(mi, 10, tab_cycle.timestamp) AS endTime, 
(SELECT COUNT(tab_event.descr) FROM tab_event  WHERE tab_event.timestamp BETWEEN tab_cycle.timestamp and DATEADD(mi, 10, tab_cycle.timestamp) AND tab_event.tag LIKE  'A' GROUP BY tag) AS eventCounter 
FROM tab_cycle
ORDER BY timestamp DESC

谁能告诉我我做错了什么?

感谢。

3 个答案:

答案 0 :(得分:1)

您只需要删除嵌套子查询中的group by

SELECT tab_cycle.timestamp AS startTime, DATEADD(mm, 10, tab_cycle.timestamp) AS endTime, 
       (SELECT COUNT(tab_event.descr)
        FROM tab_event
        WHERE tab_event.timestamp BETWEEN tab_cycle.timestamp and
                                          DATEADD(mm, 10, tab_cycle.timestamp) AND
              tab_event.tag LIKE 'A'
       ) AS eventCounter 
FROM tab_cycle
ORDER BY timestamp DESC;

编辑:

我实际上还在考虑添加此代码。您的问题的答案 - 如果您使用的是SQL Server 2012或更高版本,则使用lead()

SELECT tc.timestamp AS startTime, DATEADD(mm, 10, tc.timestamp) AS endTime, 
       (SELECT COUNT(te.descr)
        FROM tab_event te
        WHERE te.timestamp BETWEEN tc.timestamp and tc.next_timestamp AND
              te.tag LIKE 'A'
       ) AS eventCounter 
FROM (SELECT tc.*, LEAD(tc.timestamp) OVER (ORDER BY tc.timestamp) as next_timestamp 
      FROM tab_cycle tc
     ) tc
ORDER BY timestamp DESC;

我还为表名添加了缩写。这些使查询更容易编写和阅读。

如果您使用的是旧版本的SQL Server,则可以使用相关子查询或使用cross apply执行相同的操作。

答案 1 :(得分:0)

我可能会向后退一步

select table1.timestamp, table1.value1, table1.value2, table1.valueN
     , count(tabl2.timestamp) 
 from table1 
 left join table2 
   on datediff(mi, table1.timestamp, table2.timestamp) < 10 
  and table2.timestamp > table1.timestamp
group by table1.timestamp, table1.value1, table1.value2, table1.valueN

答案 2 :(得分:-1)

您只需将dateadd(mm,....)更改为dateadd(minute,...)dateadd(mi,....)

mm是几个月的简写,所以当你将它总计为例如今天的日期时,它会在结果上增加10个月。

此链接可以帮助您处理日期时间部分和相关代码:

DATEADD (Transact-SQL)