Sql 使用Group By-当试图将一个字段与另一个字段匹配时,什么是合适的聚合';斯敏

Sql 使用Group By-当试图将一个字段与另一个字段匹配时,什么是合适的聚合';斯敏,sql,sql-server-2012,aggregate-functions,Sql,Sql Server 2012,Aggregate Functions,无法确定如何完成此查询 我有一系列带有公用日志的设备。每个设备都可以有联机、脱机和处理事件。我需要计算一台设备每天“先联机,然后脱机”的次数,在此期间不进行任何处理。 注意:我对字段的内容没有发言权 也就是说,如果设备联机,那么几个条目随后会脱机,并且没有一个条目正在为此设备处理,然后将一个条目添加到计数中。如果其中一个条目是一个正在处理的条目,那么这组在线/离线条目不应添加到计数中 乙二醇 应给出装置1的以下结果: 2 1/1/01 0 2/1/01 2/1/01的0表明,如果在线和

无法确定如何完成此查询

我有一系列带有公用日志的设备。每个设备都可以有联机、脱机和处理事件。我需要计算一台设备每天“先联机,然后脱机”的次数,在此期间不进行任何处理。 注意:我对字段的内容没有发言权

也就是说,如果设备联机,那么几个条目随后会脱机,并且没有一个条目正在为此设备处理,然后将一个条目添加到计数中。如果其中一个条目是一个正在处理的条目,那么这组在线/离线条目不应添加到计数中

乙二醇

应给出装置1的以下结果:

2   1/1/01
0   2/1/01
2/1/01的0表明,如果在线和离线之间存在处理,则应将其从计数中排除。注意:脱机前可能有许多处理语句

目前我有:

SELECT      COUNT(WakeUpTime) AS NonProcessingWakeUpsPerDay
            ,DATEADD(dd, 0, DATEDIFF(dd, 0, WakeUpTime)) AS Day
FROM        (
                SELECT          MIN(DATEDIFF(SECOND, r1.Time, r2.Time)) AS WakeUpTimeSpan
                                ,CASE WHEN r2.Event LIKE 'Offline%' THEN 0 ELSE 1 END AS Processed
                                ,r1.Time AS WakeUpTime
                FROM            dbo.Record r1,
                                dbo.Record r2
                WHERE           r1.Device = @Device
                AND             r2.Device = r1.Device
                AND             r2.Time > r1.Time
                AND             r1.Event LIKE 'Online%'
                AND             (r2.Event LIKE 'Offline%' OR r2.Event LIKE 'Processing%')
                GROUP BY        r1.Time
            ) AllWakeups
WHERE       Processed = 0
GROUP BY    DATEADD(dd, 0, DATEDIFF(dd, 0, WakeUpTime))

但这在Case语句的内部查询中存在问题。我不知道如何添加聚合,因为我需要与正确的事件条目(即具有最小时间跨度的行对)相对应的值。

我想我看到了您问题的一部分,请查看以下查询:

SELECT
  CAST(r1.Time AS DATE) AS DateOnly,
  r1.Time AS StartTime,
  r2.Time AS EndTime,
  DATEDIFF(second, r1.Time, r2.Time) AS EventSeconds,
  r1.Device,
  r1.Event AS StartEvent,
  r2.Event,
  CASE
    WHEN r2.Event LIKE 'Offline%' THEN 0
    ELSE 1
  END AS Processed
FROM Record r1
JOIN Record r2
  ON r1.Device = r2.Device
  AND r2.Time > r1.Time
  AND r1.Event LIKE 'Online%'
  AND (
    r2.Event LIKE 'Offline%'
    OR r2.Event LIKE 'Processing%'
  )
WHERE r1.Device = 1
对于您的示例数据,仅使用设备1,我们将获得每个开始时间的多条记录,我相信您可能只希望按时间顺序匹配下一条记录

例如,“Online 123”正在加入到“Offline 124”、“Offline 128”、“Processing 132”和“Offline 134”,但应该只加入到“Offline 124”(因此需要具有最小时间跨度的行)

<>您可以查看数据分区,考虑以下内容:

;WITH cte AS
(
  SELECT
    r.Time,
    r.Device,
    r.Event,
    ROW_NUMBER() OVER(PARTITION BY r.Device ORDER BY r.Time) AS RowNumber
  FROM @Record r
 )
SELECT r1.Event, r2.Event
FROM cte r1
JOIN cte r2
  ON r1.Device = r2.Device
  AND r2.RowNumber = (r1.RowNumber + 1)
  AND r1.Event LIKE 'Online%'
这将提供以下输出对:

Online 123  Offline 124
Online 126  Offline 128
Online 130  Processing 132
Online 125  Processing 127
Online 131  Processing 133
从拥有正确的数据对这一基点出发,您可以继续获得所需的实际数据。看看这个:

;WITH cte AS
(
  SELECT
    r.Time,
    r.Device,
    r.Event,
    ROW_NUMBER() OVER(PARTITION BY r.Device ORDER BY r.Time) AS RowNumber
  FROM Record r
),
byDateCTE AS
(
    SELECT 
        CAST(r1.Time AS DATE) AS EventDate,
        CASE WHEN r2.Event LIKE 'Processing%' THEN 1 ELSE 0 END AS Processed,
        CASE WHEN r2.Event LIKE 'Offline%' THEN 1 ELSE 0 END AS UnProcessed
    FROM cte r1
    JOIN cte r2
      ON r1.Device = r2.Device
      AND r2.RowNumber = (r1.RowNumber + 1)
      AND r1.Event LIKE 'Online%'
)
SELECT
    EventDate,
    SUM(Processed) AS Processed,
    SUM(UnProcessed) AS UnProcessed
FROM byDateCTE
GROUP BY EventDate
输出:

EventDate   Processed  UnProcessed
2001-01-01  1          2
2001-01-02  2          0

您是否只想按日期分组,而忽略时间?是的,由于存在跨越日期边界的线上-线下时段,因此应将线上时段用作分组的基础。您能否解释您的结果。2和0是什么意思?日期内在线>处理>离线序列的计数?2/1/01不应该是1吗?如果不是,为什么是0?事实上我理解你的要求。。但不是你的问题。。为什么要自行加入?一对之间的“最小时间跨度”有什么意义?看起来你想要一个秒数,但你也在比较天数的差异?你能更清楚地说明你的预期结果吗?谢谢。这看起来不错。我一直在努力正确使用分区。我会接受答案,只要我验证它的实际数据工作。
EventDate   Processed  UnProcessed
2001-01-01  1          2
2001-01-02  2          0