【问题标题】:Mysql find id gaps in temporary tableMysql在临时表中查找id间隙
【发布时间】:2016-02-24 12:15:13
【问题描述】:

我需要在临时表的整数字段中查找 id 间隙。 由于临时表的限制,我无法打开表两次并将其加入自身。

这是一个例子:

CREATE TEMPORARY TABLE tmp_table (
    id int(8) unsigned,
    PRIMARY KEY (id)
);

INSERT INTO tmp_table VALUES (1),(2),(4),(7),(10),(11),(13);

我想在这里找到这个结果集:

3, 5, [6], 8, [9], 12

[#]=可选

【问题讨论】:

  • @mitkosoft 很好的尝试,但我的问题不同,因为我使用的是临时表。
  • 我想知道为什么我得到一个-1...不清楚的问题?复仇?
  • 不是我的老兄,对我来说这个问题很有价值。
  • 不是我的。有用的问题很多人不会记得临时表的限制。

标签: mysql temp-tables


【解决方案1】:

一种可行的解决方案,但可能是更好的解决方案。

这会生成一个数字范围(因此您需要针对更大的范围对其进行修改 - 这最多可以处理 1000 个),并针对临时表交叉连接该范围。它从临时表中找到大于或等于或小于或等于(分别)生成值的最大和最小 ID。然后在 HAVING 子句中检查更大/更少的值是否不相等也不为空

SELECT 1 + units.i + tens.i * 10 + hundreds.i * 100 AS poss_num, 
        MAX(IF(tmp_table.id <= 1 + units.i + tens.i * 10 + hundreds.i * 100, tmp_table.id, NULL)) AS max_id, 
        MIN(IF(tmp_table.id >= 1 + units.i + tens.i * 10 + hundreds.i * 100, tmp_table.id, NULL)) AS min_id
FROM 
(
    SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) units
CROSS JOIN
(
    SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) tens
CROSS JOIN
(
    SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) hundreds
CROSS JOIN tmp_table
GROUP BY poss_num
HAVING min_id != max_id
AND min_id IS NOT NULL
AND max_id IS NOT NULL

【讨论】:

  • 这是一个非常原始的解决方案,主要问题是我必须预测 id 边界,实际上我正在使用完整的 usigned Int 大小 (4294967295)
  • @Tobia - 扩大范围的大小很容易,但不确定它是否会导致问题变得那么大!您还可以加入另一个具有完整 ID 范围的随机表(您可以提前生成)。避免超过您的最大 id 的数字使其变得复杂。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多