【问题标题】:Select Row w/ Value Y after Row w/ Value X & Efficiency在带值 X 和效率的行之后选择带值 Y 的行
【发布时间】:2021-05-31 22:23:42
【问题描述】:
  • MySQL 8.0.25(主要使用 HeidiSQL,但有时也使用命令行)

  • Windows 10(专用 MySQL 机器)

  • 128GB 内存

  • 用于操作系统和数据驱动器的单独 SSD

  • Temp DIR 指向具有 600GB 可用空间的数据驱动器

  • 我正在查询的数据超过 8200 万行,大小约为 18GB

我有什么

ID signal
1 x
2 x
3 y
4 x
5 y
6 y
7 y
8 x
9 y
10 x
11 y

我需要什么

X ID Y ID
1 3
4 5
8 9
10 11

解释:

基本上,我在单列中有一个变量列表(X 和 Y)。我需要找到 X,然后在 X 的行之后找到带有 Y 的下一行。但是,有时,如上例所示,有多个 X 和 Y 相互重复(即第 1 行和第 2 行)。我需要第一个 X,然后是第一个 Y(并跳过重复 X 的行)。

下一个选择的 X 将位于先前使用的行中的 Y 之后。即,第 4 行的 X 将是第一个结果行之后的下一个,并且永远不会使用第 2 行中的 X。

我试过了:

SELECT
    x_tbl.id,
    (
        SELECT
            y_tbl.id
        FROM
            t_table AS y_tbl
        WHERE
            signal = "y"
            AND
            MIN(y_tbl.id) > x_tbl.id
        LIMIT
            1
    ) y_id
FROM
    t_table AS x_tbl
WHERE
    x_tbl.signal = "x"

问题是 InnoDB 会重新扫描整个数据库。单身的。排。我的真实代码是从原始表中提取数据,然后通过一些 CTE 过滤掉数据量,然后再执行此步骤(例如数据等)。从我的测试来看,这确实有助于加快速度——但在整个数据库中运行它实际上需要 10 多天才能完成。太疯狂了。

有没有更有效的方法来写这个?

【问题讨论】:

  • 这些方面的东西怎么样...stackoverflow.com/questions/67553864/…
  • 感谢您的回复!在理解您的示例时,我大约有 75% 的人在那里 - 但不完全确定为什么在“grp”字段中,您要减去一个密集排名(用户 ID)和组合密集排名(用户 ID、状态)。你能解释一下如何/为什么这样做吗?我怀疑这与将“最新”状态更改置于更高/更低级别有关 - 但不完全确定......
  • 请参阅db-fiddle.com/f/3PS7gV64j1gkXdbvgtPKC8/0 了解一些细分...这里我们对状态更改感兴趣。每当 x 减去 y 的结果与“上一个”行中的结果不同时,就会发生这种情况。
  • 这太棒了,顺便说一句。但是,如果我想包括状态更改本身的日期(即在您的示例中,不是开始和结束日期具有相同的状态,我想要第一个状态的开始日期,然后“更改”状态本身的日期作为完成日期)?我会使用某种将 1 添加到完成日期行,或者可能是 LEAD(MIN(date)) 类型的东西吗?只是为了澄清-我想要的输出是:| 1 | GRE | 2018-09-02 | 2018-09-04 | | 1 |专业 | 2018-09-04 | 2018-09-07 |谢谢!
  • 这听起来完全不同,足以证明一个问题本身。好消息是,您现在可以使用工具来提出这个问题。

标签: mysql


【解决方案1】:

一个想法……

  1. 使用LEAD()(或LAG())过滤掉带有dup signals的行。
  2. 添加一个新的AUTO_INCREMENT 列。这是为了获取行号。 (我不知道这个老把戏比使用ROW_NUMBER() 快还是慢。)
  3. 执行自联接以根据新行号配对偶数/奇数行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 2011-07-04
    • 2011-11-10
    • 2023-02-01
    • 2022-07-13
    • 2018-05-11
    相关资源
    最近更新 更多