sql - 同一列中的日期差异,基于表的值

标签 sql sql-server

表格格式如下。

Id     name    value      logdatetime
*************************************************
1       a       65         2017-03-08 00:13:00.000
2       a       63         2017-03-08 00:14:00.000
3       a       72         2017-03-08 00:15:00.000
4       a       120        2017-03-08 00:16:00.000
5       a       45         2017-03-08 00:17:00.000
6       a       32         2017-03-08 00:18:00.000
7       a       53         2017-03-08 00:19:00.000
8       a       59         2017-03-08 00:20:00.000
9       a       21         2017-03-08 00:21:00.000

从上表我需要使用sql查询生成下表,它基本上必须检查大于50的值并显示如下数据

name     startdate                           enddate
********************************************************************
a        2017-03-08 00:13:00.000             2017-03-08 00:16:00.000
a        2017-03-08 00:19:00.000             2017-03-08 00:21:00.000

请帮我解决这个问题。

最佳答案

尝试使用以下内容

CREATE TABLE #TestData(
  Id int,
  name varchar(10),
  value int,
  logdatetime datetime
)

INSERT #TestData(Id,name,value,logdatetime)VALUES
(1,'a',65,'2017-03-08 00:13:00.000'),
(2,'a',63,'2017-03-08 00:14:00.000'),
(3,'a',72,'2017-03-08 00:15:00.000'),
(4,'a',120,'2017-03-08 00:16:00.000'),
(5,'a',45,'2017-03-08 00:17:00.000'), -- separator 1
(6,'a',32,'2017-03-08 00:18:00.000'), -- separator 2
(7,'a',53,'2017-03-08 00:19:00.000'),
(8,'a',59,'2017-03-08 00:20:00.000'),
(9,'a',21,'2017-03-08 00:21:00.000') -- separator 3


SELECT
  name,
  MIN(logdatetime) [start time],
  MAX(logdatetime) [end time]
FROM
  (
    SELECT
      *,
      SUM(IsSeparator)OVER(
                            PARTITION BY name
                            ORDER BY logdatetime,Id
                            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
                          ) SeparatorCount
    FROM
      (
        SELECT
          *,
          --IIF(value<=50,1,0) IsSeparator -- it's a special marker
          CASE WHEN value<=50 THEN 1 ELSE 0 END IsSeparator -- you can use CASE instead IIF
        FROM #TestData
      ) q
  ) q
WHERE value>50 -- exclude values less 50
GROUP BY name,SeparatorCount -- use SeparatorCount here

DROP TABLE #TestData

我在 SQLServer 2014 上测试过它。

SQL fiddle -http://sqlfiddle.com/#!6/ff80e/1

或者你可以使用递归 CTE 的另一个变体

;WITH numCTE AS(
  SELECT *,ROW_NUMBER()OVER(PARTITION BY name ORDER BY logdatetime,Id) n
  FROM #TestData
),
groupCTE AS(
  SELECT name,logdatetime,value,n,1 groupNum
  FROM numCTE
  WHERE n=1

  UNION ALL

  SELECT n.name,n.logdatetime,n.value,n.n,
    --g.groupNum+IIF(n.value<=50,1,0) 
    g.groupNum+CASE WHEN n.value<=50 THEN 1 ELSE 0 END 
  FROM numCTE n
  JOIN groupCTE g ON n.name=g.name AND n.n=g.n+1
)
SELECT
  name,
  MIN(logdatetime) [start time],
  MAX(logdatetime) [end time]
FROM groupCTE
WHERE value>50
GROUP BY name,groupNum

但我认为第一个变体更好。

还有一个变体。它比第一个变体短。

SELECT
  name,
  MIN(logdatetime) [start time],
  MAX(logdatetime) [end time]
FROM
  (
    SELECT
      *,
      SUM(CASE WHEN value<=50 THEN 1 ELSE 0 END)OVER(
              PARTITION BY name
              ORDER BY logdatetime,Id
              ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
            ) groupNum
    FROM #TestData
  ) q
WHERE value>50
GROUP BY name,groupNum

关于sql - 同一列中的日期差异,基于表的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47827475/

相关文章:

sql-server - SSIS 日志记录到 SQL Server

sql - amazon athena - 从多个表中选择而不连接

SQL 脚本 : How to write ALTER statements to set Primary key on an existing table?

php - 对 SQL 表中的 2 列进行计数并分组

php - cakePHP 查找 ("list") 返回空数组

php - mssql 中的 php time() 等价物是什么?

.net - 内部连接 fatal error

sql - 如何使用 SQL Server 在变量中创建 Insert with Select 查询

java - Android - 将行插入 SQLite DB

mysql - SQL搜索无重复