AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 102064
Accepted
jpmc26
jpmc26
Asked: 2015-05-21 08:34:46 +0800 CST2015-05-21 08:34:46 +0800 CST 2015-05-21 08:34:46 +0800 CST

如何找到数字范围之间的差距?

  • 772

考虑下表:

T_ID | T_START | T_END
-----+---------+------
   1 | 0.25    | 0.5
   2 | 0.8     | 1
   3 | 0.4     | 0.6
   4 | 0.2     | 0.3
   5 | 0.7     | 0.8

T_ID是独特的。每行代表一个连续的数字范围,是 0 到 1 的子集。T_START小于T_END。

我需要确定不包含在 0 和 1 之间的任何范围。请注意,某些范围确实重叠。端点的排他性与我的用例无关;我只需要确定差距的端点是什么。(因此,不考虑单点差距。)

对于这个特定的数据集,我希望结果是

GAP_START | GAP_END
----------+--------
0         | 0.2
0.6       | 0.7

实际数据集很大,并且将聚合到其他一些数据(数十万行,每个聚合组可能有 100 行),因此性能很重要。(不过,欢迎提供性能不佳但可能会改进的答案。)

我考虑尝试首先确定覆盖范围是什么,然后尝试反转它,但我什至无法弄清楚如何计算覆盖范围。简单GROUP BY是不够的,因为我们有重叠范围的链,它们将合并到一个范围中,即使并非所有范围都相互重叠。我认为递归查询可能会有所帮助,但我还没有弄清楚它的逻辑。

我用这个示例数据集创建了一个 SQLFiddle 。

可悲的是(而且毫无成效),我不能随意修改底层表示。

oracle oracle-11g-r2
  • 1 1 个回答
  • 4616 Views

1 个回答

  • Voted
  1. Best Answer
    jpmc26
    2015-05-21T10:27:01+08:002015-05-21T10:27:01+08:00

    经过相当多的挖掘后,我发现这篇关于为日期范围执行此操作的博客文章,结果证明它在数字范围上同样适用,只需稍作修改即可处理 0 和 1 端点。

    从那里获取查询并将列重命名为更清晰,我们有

    SELECT * FROM
      (SELECT MAX(T_END) OVER (ORDER BY T_START) GAP_START,
              LEAD(T_START) OVER (ORDER BY T_START) GAP_END
       FROM T)
    WHERE GAP_START < GAP_END
    

    这需要相当多的解释。一步步:

    1. 对于每一行,它从小于或等于当前行的T_END所有行中获取最大值。这为我们提供了与该行的范围开始重叠的所有范围的最大范围结束。T_STARTT_START
    2. 对于每一行,它获取大于当前行T_START的第一行的。T_START这给了我们下一个最大的范围开始。
    3. T_END它过滤掉最大值大于或等于 next的任何行T_START。这意味着最大的重叠范围结束延伸到或超出下一个范围开始。换句话说,这一行和下一行之间没有间隙,要么是因为这一行在下一行开始的地方结束,要么是因为其他重叠的行覆盖了两者之间的所有点。

    但是,这并不能完全满足 0 到 1 范围内的所有间隙的要求。它只选择所有行的最小范围开始和最大范围结束之间的间隙。要检查 0 和 1 范围末端的间隙,我们可以使用以下查询。

    对于从 0 开始的间隙:

    SELECT 0 AS GAP_START, MIN(T_START) AS GAP_END
    FROM T
    HAVING MIN(T_START) > 0
    

    对于以 1 结尾的间隙:

    SELECT MAX(T_END) AS GAP_START, 1 AS GAP_END
    FROM T
    HAVING MAX(T_END) < 1
    

    如果端点没有间隙,这两个查询都不会返回任何行。

    将它们放在一个查询中:

    SELECT * FROM
      (SELECT MAX(T_END) OVER (ORDER BY T_START) GAP_START,
              LEAD(T_START) OVER (ORDER BY T_START) GAP_END
       FROM T)
    WHERE GAP_START < GAP_END
    UNION ALL
    SELECT 0 AS GAP_START, MIN(T_START) AS GAP_END
    FROM T
    HAVING MIN(T_START) > 0
    UNION ALL
    SELECT MAX(T_END) AS GAP_START, 1 AS GAP_END
    FROM T
    HAVING MAX(T_END) < 1
    

    结果与问题中所述完全相同,忽略顺序。SQLFiddle 的查询。

    • 5

相关问题

  • Oracle 中的数据库备份 - 导出数据库还是使用其他工具?

  • ORDER BY 使用文本列的自定义优先级

  • 舒服的sqlplus界面?[关闭]

  • 如何在数据库中找到最新的 SQL 语句?

  • 如何使用正则表达式查询名称?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve