Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL-选择列值更改前后带有日期的行_Sql_Sql Server - Fatal编程技术网

SQL-选择列值更改前后带有日期的行

SQL-选择列值更改前后带有日期的行,sql,sql-server,Sql,Sql Server,我有一张表叫test。 在测试中,我有一个ID、一个值和一个日期。 为每个ID排序日期。 我想在值更改前后为ID选择行,因此下面的示例表如下所示 RowNum---ID---Value---Date 1---------001 -----1------ 01/01/2015 2---------001 -----1------ 02/01/2015 3---------001 -----1------ 04/01/2015 4---------001 -----1------ 05/01/201

我有一张表叫test。 在测试中,我有一个ID、一个值和一个日期。 为每个ID排序日期。 我想在值更改前后为ID选择行,因此下面的示例表如下所示

RowNum---ID---Value---Date 1---------001 -----1------ 01/01/2015 2---------001 -----1------ 02/01/2015 3---------001 -----1------ 04/01/2015 4---------001 -----1------ 05/01/2015 5---------001 -----1------ 06/01/2015 6---------001 -----1------ 08/01/2015 7---------001 -----0------ 09/01/2015 8---------001 -----0------ 10/01/2015 9---------001 -----0------ 11/01/2015 10---------001 -----1------ 12/01/2015 11---------001 -----1------ 14/01/2015 12---------002 -----1------ 01/01/2015 13---------002 -----1------ 04/01/2015 14---------002 -----0------ 05/01/2015 15-----------002-------0-------2015年1月7日


结果将返回第6行、第7行、第9行、第10行、第13行、第14行。您可以使用分析函数LAG和LEAD来访问前一行和后一行中的值,然后检查它是否与当前行中的值不匹配

SELECT *
FROM   (
  SELECT RowNum,
         ID,
         Value,
         Date,
         LAG(VALUE, 1, VALUE)  OVER(ORDER BY RowNum)  PrevValue,
         LEAD(VALUE, 1, VALUE) OVER(ORDER BY RowNum)  NextValue
  FROM   test)
WHERE PrevValue <> Value
OR    NextValue <> Value
传递给此函数的参数为

本例中的一些标量表达式列名; 前后偏移1行; 默认值LAG将为第一行返回NULL,LEAD将为最后一行返回NULL,但在您的问题中它们似乎并不特别,所以我使用列值作为默认值。
您可以使用分析函数LAG和LEAD访问前面和后面行中的值,然后检查它是否与当前行中的值不匹配

SELECT *
FROM   (
  SELECT RowNum,
         ID,
         Value,
         Date,
         LAG(VALUE, 1, VALUE)  OVER(ORDER BY RowNum)  PrevValue,
         LEAD(VALUE, 1, VALUE) OVER(ORDER BY RowNum)  NextValue
  FROM   test)
WHERE PrevValue <> Value
OR    NextValue <> Value
传递给此函数的参数为

本例中的一些标量表达式列名; 前后偏移1行; 默认值LAG将为第一行返回NULL,LEAD将为最后一行返回NULL,但在您的问题中它们似乎并不特别,所以我使用列值作为默认值。
在不使用超前和滞后的情况下,参考以下一项:

DECLARE @i        INT = 1, 
        @cnt      INT, 
        @dstvalue INT, 
        @srcvalue INT 

CREATE TABLE #result 
  ( 
     id     INT, 
     mydate DATE 
  ) 

CREATE TABLE #temp1 
  ( 
     rn     INT IDENTITY(1, 1), 
     id     INT, 
     mydate DATE 
  ) 

INSERT INTO #temp1 
            (id, 
             mydate) 
SELECT id, 
       mydate 
FROM   table 
ORDER  BY id, 
          mydate 

SELECT @cnt = Count(*) 
FROM   #temp1 

SELECT @srcvalue = value 
FROM   #temp1 
WHERE  rn = @i 

WHILE ( @i <= @cnt ) 
  BEGIN 
      SELECT @dstvalue = value 
      FROM   #temp1 
      WHERE  rn = @i 

      IF( @srcvalue = @dstvalue ) 
        BEGIN 
            SET @i = @i + 1 

            CONTINUE; 
        END 
      ELSE 
        BEGIN 
            SET @srcvalue = @dstvalue 

            INSERT INTO #result 
                        (id, 
                         mydate) 
            SELECT id, 
                   mydate 
            FROM   #temp 
            WHERE  rn = @i - 1 
            UNION ALL 
            SELECT id, 
                   mydate 
            FROM   #temp 
            WHERE  rn = @i 
        END 

      SET @i = @i + 1 
  END 

SELECT * 
FROM   #result 

在不使用超前和滞后的情况下,参考以下一项:

DECLARE @i        INT = 1, 
        @cnt      INT, 
        @dstvalue INT, 
        @srcvalue INT 

CREATE TABLE #result 
  ( 
     id     INT, 
     mydate DATE 
  ) 

CREATE TABLE #temp1 
  ( 
     rn     INT IDENTITY(1, 1), 
     id     INT, 
     mydate DATE 
  ) 

INSERT INTO #temp1 
            (id, 
             mydate) 
SELECT id, 
       mydate 
FROM   table 
ORDER  BY id, 
          mydate 

SELECT @cnt = Count(*) 
FROM   #temp1 

SELECT @srcvalue = value 
FROM   #temp1 
WHERE  rn = @i 

WHILE ( @i <= @cnt ) 
  BEGIN 
      SELECT @dstvalue = value 
      FROM   #temp1 
      WHERE  rn = @i 

      IF( @srcvalue = @dstvalue ) 
        BEGIN 
            SET @i = @i + 1 

            CONTINUE; 
        END 
      ELSE 
        BEGIN 
            SET @srcvalue = @dstvalue 

            INSERT INTO #result 
                        (id, 
                         mydate) 
            SELECT id, 
                   mydate 
            FROM   #temp 
            WHERE  rn = @i - 1 
            UNION ALL 
            SELECT id, 
                   mydate 
            FROM   #temp 
            WHERE  rn = @i 
        END 

      SET @i = @i + 1 
  END 

SELECT * 
FROM   #result 
使用滞后和超前的答案是正确的答案。如果您使用的是SQL Server 2012之前的版本,则可以使用交叉应用或相关子查询执行基本相同的操作:

select t.*
from test t cross apply
     (select top 1 tprev.*
      from test tprev
      where tprev.date < t.date
      order by date desc
     ) tprev cross apply
     (select top 1 tnext.*
      from test tnext
      where tnext.date > t.date
      order by date asc
     ) tnext 
where tprev.value <> tnext.value;
使用滞后和超前的答案是正确的答案。如果您使用的是SQL Server 2012之前的版本,则可以使用交叉应用或相关子查询执行基本相同的操作:

select t.*
from test t cross apply
     (select top 1 tprev.*
      from test tprev
      where tprev.date < t.date
      order by date desc
     ) tprev cross apply
     (select top 1 tnext.*
      from test tnext
      where tnext.date > t.date
      order by date asc
     ) tnext 
where tprev.value <> tnext.value;

我可以知道SQL Server的版本吗?解决方案会有所不同我可以知道SQL Server的版本吗?解决方案会有相应的不同