Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.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/1/oracle/10.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_Oracle - Fatal编程技术网

Sql 从数字序列中获取非更改值的间隔

Sql 从数字序列中获取非更改值的间隔,sql,oracle,Sql,Oracle,我需要将一系列值汇总为非变化值的区间——每个区间的开始、结束和值。我可以很容易地用plsql实现这一点,但出于性能和教育方面的原因,我想要一个纯sql解决方案。一段时间以来,我一直在尝试用分析函数来解决这个问题,但不知道如何正确定义windowing子句。我遇到的问题是重复值 简化示例- 给定输入: id value 1 1 2 1 3 2 4 2 5 1 我想得到输出 from to val 1 2 1 3 4 2 5 5 1 您希望标识

我需要将一系列值汇总为非变化值的区间——每个区间的开始、结束和值。我可以很容易地用plsql实现这一点,但出于性能和教育方面的原因,我想要一个纯sql解决方案。一段时间以来,我一直在尝试用分析函数来解决这个问题,但不知道如何正确定义windowing子句。我遇到的问题是重复值

简化示例- 给定输入:

id  value
1   1
2   1
3   2
4   2
5   1
我想得到输出

from to val
1    2   1
3    4   2
5    5   1

您希望标识相邻值的组。一种方法是使用
lag()

另一种方法是行号的差异:

select value, min(id) as from_id, max(id) as to_id
from (select t.*,
             (row_number() over (order by id) -
              row_number() over (partition by val order by id
             ) as grp
      from table t
     ) t
group by grp, value;

您希望标识相邻值的组。一种方法是使用
lag()

另一种方法是行号的差异:

select value, min(id) as from_id, max(id) as to_id
from (select t.*,
             (row_number() over (order by id) -
              row_number() over (partition by val order by id
             ) as grp
      from table t
     ) t
group by grp, value;

您希望标识相邻值的组。一种方法是使用
lag()

另一种方法是行号的差异:

select value, min(id) as from_id, max(id) as to_id
from (select t.*,
             (row_number() over (order by id) -
              row_number() over (partition by val order by id
             ) as grp
      from table t
     ) t
group by grp, value;

您希望标识相邻值的组。一种方法是使用
lag()

另一种方法是行号的差异:

select value, min(id) as from_id, max(id) as to_id
from (select t.*,
             (row_number() over (order by id) -
              row_number() over (partition by val order by id
             ) as grp
      from table t
     ) t
group by grp, value;

使用CTE收集所有行并将它们标识为变化的值,最后将这些变化的值分组在一起

CREATE TABLE #temp (
    ID      INT NOT NULL IDENTITY(1,1),
    [Value] INT NOT NULL
)
GO

INSERT INTO #temp ([Value]) 
    SELECT 1 UNION ALL
    SELECT 1 UNION ALL
    SELECT 2 UNION ALL
    SELECT 2 UNION ALL
    SELECT 1;


WITH Marked AS (
  SELECT
    *,
    grp = ROW_NUMBER() OVER (ORDER BY ID)
        - ROW_NUMBER() OVER (PARTITION BY Value     ORDER BY ID)
  FROM #temp
)
SELECT MIN(ID) AS [From], MAX(ID) AS [To], [VALUE]
FROM Marked
GROUP BY grp, Value
ORDER BY MIN(ID)

DROP TABLE #temp;

使用CTE收集所有行并将它们标识为变化的值,最后将这些变化的值分组在一起

CREATE TABLE #temp (
    ID      INT NOT NULL IDENTITY(1,1),
    [Value] INT NOT NULL
)
GO

INSERT INTO #temp ([Value]) 
    SELECT 1 UNION ALL
    SELECT 1 UNION ALL
    SELECT 2 UNION ALL
    SELECT 2 UNION ALL
    SELECT 1;


WITH Marked AS (
  SELECT
    *,
    grp = ROW_NUMBER() OVER (ORDER BY ID)
        - ROW_NUMBER() OVER (PARTITION BY Value     ORDER BY ID)
  FROM #temp
)
SELECT MIN(ID) AS [From], MAX(ID) AS [To], [VALUE]
FROM Marked
GROUP BY grp, Value
ORDER BY MIN(ID)

DROP TABLE #temp;

使用CTE收集所有行并将它们标识为变化的值,最后将这些变化的值分组在一起

CREATE TABLE #temp (
    ID      INT NOT NULL IDENTITY(1,1),
    [Value] INT NOT NULL
)
GO

INSERT INTO #temp ([Value]) 
    SELECT 1 UNION ALL
    SELECT 1 UNION ALL
    SELECT 2 UNION ALL
    SELECT 2 UNION ALL
    SELECT 1;


WITH Marked AS (
  SELECT
    *,
    grp = ROW_NUMBER() OVER (ORDER BY ID)
        - ROW_NUMBER() OVER (PARTITION BY Value     ORDER BY ID)
  FROM #temp
)
SELECT MIN(ID) AS [From], MAX(ID) AS [To], [VALUE]
FROM Marked
GROUP BY grp, Value
ORDER BY MIN(ID)

DROP TABLE #temp;

使用CTE收集所有行并将它们标识为变化的值,最后将这些变化的值分组在一起

CREATE TABLE #temp (
    ID      INT NOT NULL IDENTITY(1,1),
    [Value] INT NOT NULL
)
GO

INSERT INTO #temp ([Value]) 
    SELECT 1 UNION ALL
    SELECT 1 UNION ALL
    SELECT 2 UNION ALL
    SELECT 2 UNION ALL
    SELECT 1;


WITH Marked AS (
  SELECT
    *,
    grp = ROW_NUMBER() OVER (ORDER BY ID)
        - ROW_NUMBER() OVER (PARTITION BY Value     ORDER BY ID)
  FROM #temp
)
SELECT MIN(ID) AS [From], MAX(ID) AS [To], [VALUE]
FROM Marked
GROUP BY grp, Value
ORDER BY MIN(ID)

DROP TABLE #temp;

这不是有效的Oracle语法(看起来像SQL Server)。@FrankSchmitt oops你是对的。只是刚刚注意到标记是orcale和sql(不是sql server),这是无效的Oracle语法(看起来像sql server)。@FrankSchmitt oops你说得对。只是刚刚注意到标记是orcale和sql(不是sql server),这是无效的Oracle语法(看起来像sql server)。@FrankSchmitt oops你说得对。只是刚刚注意到标记是orcale和sql(不是sql server),这是无效的Oracle语法(看起来像sql server)。@FrankSchmitt oops你说得对。只是刚刚注意到标签是orcale和sql(不是sql server),我猜lag/lead会有帮助,但这对第一行/最后一行有额外的工作,“本质上”是一个过程解决方案。您使用rownumber来区分相同值的非相邻组的“技巧”非常好。今天我学到了一些东西:-)。我猜滞后/超前会有帮助,但这对第一行/最后一行有额外的工作,而且“本质上”是一个程序性的解决方案。您使用rownumber来区分相同值的非相邻组的“技巧”非常好。今天我学到了一些东西:-)。我猜滞后/超前会有帮助,但这对第一行/最后一行有额外的工作,而且“本质上”是一个程序性的解决方案。您使用rownumber来区分相同值的非相邻组的“技巧”非常好。今天我学到了一些东西:-)。我猜滞后/超前会有帮助,但这对第一行/最后一行有额外的工作,而且“本质上”是一个程序性的解决方案。您使用rownumber来区分相同值的非相邻组的“技巧”非常好。今天我学到了一些东西:-)。