我们有一张带有ID
自动增量列的表格,其中包含间隙。每行还有一个created
日期。
我们正在尝试找出每个差距ID(缺失的ID)我们表格中可用的上一个/下一个日期。
我们已经构建了一个用于识别差距的SQL(来自here的解决方案),因此我将它们放在缓存的表中,但是从这里可以找到涵盖该范围的上一个/下一个created
日期与原始表格的差距。
输入:
+----+------------+
| 84 | 1443728132 |
| 91 | 1443728489 |
| 93 | 1443729058 |
| 94 | 1443729200 |
+----+------------+
输出
+--------+------------+------------+
| gap_id | prev_dt | next_dt |
+--------+------------+------------+
| 85 | 1443728132 | 1443728489 |
| 86 | 1443728132 | 1443728489 |
| 87 | 1443728132 | 1443728489 |
| 88 | 1443728132 | 1443728489 |
| 89 | 1443728132 | 1443728489 |
| 90 | 1443728132 | 1443728489 |
| 92 | 1443728489 | 1443729058 |
+--------+------------+------------+
我最终使用Google BigQuery。
答案 0 :(得分:2)
我建议将结果分组到范围内:
select min(id + 1) as first_missing_id,
(next_id - 1) as last_missing_id,
next_dte
from (select t.*,
lead(id) over (order by id) as next_id,
lead(dte) over (order by id) as next_dte
from t
) t
where next_id <> id + 1
group by next_id, next_dte;
获取个人ID非常棘手。毕竟,如果你有1,1000000,1000000000那么你可能会产生很多行。
答案 1 :(得分:1)
应该适用于MySQL以外的大多数数据库
select *
from (select lag (id) over (order by id) + 1 as gap_start
,id - 1 as gap_end
,lag (dt) over (order by id) as dt_before_gap
,dt as dt_after_gap
,case when lag (id) over (order by id) + 1 <> id then 'Y' end as is_gap
from t
) t
where is_gap = 'Y'
;
答案 2 :(得分:1)
对于BigQuery Standard SQL
WITH yourTable AS (
SELECT 84 AS id, 1443728132 AS dt UNION ALL
SELECT 91 AS id, 1443728489 AS dt UNION ALL
SELECT 93 AS id, 1443729058 AS dt UNION ALL
SELECT 94 AS id, 1443729200 AS dt
),
nums AS (
SELECT num
FROM UNNEST(GENERATE_ARRAY((SELECT MIN(id) FROM YourTable), (SELECT MAX(id) FROM YourTable))) AS num
),
gaps AS (
SELECT
LAG (id) OVER (ORDER BY id) + 1 AS gap_start,
id - 1 AS gap_end,
LAG (dt) OVER (ORDER BY id) AS prev_dt,
dt AS next_dt,
CASE
WHEN LAG (id) OVER (ORDER BY id) + 1 <> id THEN 'Y'
END AS is_gap
FROM
yourTable
)
SELECT num as gap_id, prev_dt, next_dt
FROM gaps JOIN nums
ON num BETWEEN gap_start AND gap_end
WHERE is_gap = 'Y'
ORDER BY num
输出:
gap_id prev_dt next_dt
85 1443728132 1443728489
86 1443728132 1443728489
87 1443728132 1443728489
88 1443728132 1443728489
89 1443728132 1443728489
90 1443728132 1443728489
92 1443728489 1443729058