正直に言いましょう!
別の実用的な解決策は、問題に提示されているよりも優れています-1つの単純な理由で-それは間違っています! 欠落している数値はまったく返されません。むしろ、次のギャップの後に番号が表示されます。それだけです(私がこれに目を向けてくれたことに感謝してください)
さて、より良い解決策について - 追求すべき選択肢はたくさんあります。
注: 以下のオプションは BigQuery 専用です。
オプション1
BigQuery 標準 SQL -標準 SQLを有効にする方法を参照
WITH YourTable AS (
SELECT 1 AS x UNION ALL
SELECT 2 AS x UNION ALL
SELECT 3 AS x UNION ALL
SELECT 6 AS x UNION ALL
SELECT 8 AS x UNION ALL
SELECT 10 AS x UNION ALL
SELECT 11 AS x
),
nums AS (
SELECT num
FROM UNNEST(GENERATE_ARRAY((SELECT MIN(x) FROM YourTable), (SELECT MAX(x) FROM YourTable))) AS num
)
SELECT num FROM nums
LEFT JOIN YourTable ON num = x
WHERE x IS NULL
ORDER BY num
オプション 2
以下で試すことができるBigQuery レガシー SQL (ここでは、nums テーブルの select 式内に start/min および end/max 値を設定する必要があります
SELECT num FROM (
SELECT num FROM (
SELECT ROW_NUMBER() OVER() AS num, *
FROM (FLATTEN((SELECT SPLIT(RPAD('', 11, '.'),'') AS h FROM (SELECT NULL)), h))
) WHERE num BETWEEN 1 AND 11
) AS nums
LEFT JOIN (
SELECT x FROM
(SELECT 1 AS x),
(SELECT 2 AS x),
(SELECT 3 AS x),
(SELECT 6 AS x),
(SELECT 8 AS x),
(SELECT 10 AS x),
(SELECT 11 AS x)
) AS YourTable
ON num = x
WHERE x IS NULL
オプション 3
BigQuery レガシー SQL - 最小値と最大値に依存せず、それらの値を設定する必要がある場合は、以下のソリューションを使用できます。必要なのは、予想される成長に対応するのに十分な最大値を設定することだけです (たとえば、1000 を入れます)。
SELECT num FROM (
SELECT num FROM (
SELECT ROW_NUMBER() OVER() AS num, *
FROM (FLATTEN((SELECT SPLIT(RPAD('', 1000, '.'),'') AS h FROM (SELECT NULL)), h))
) WHERE num BETWEEN 1 AND 1000
) AS nums
LEFT JOIN YourTable
ON num = x
WHERE x IS NULL
AND num BETWEEN (SELECT MIN(x) FROM YourTable) AND (SELECT MAX(x) FROM YourTable)
オプション 4 (何らかの理由で - これまでのお気に入り)
BigQuery 標準 SQL - 明示的な結合なし
WITH YourTable AS (
SELECT 1 AS x UNION ALL
SELECT 2 AS x UNION ALL
SELECT 3 AS x UNION ALL
SELECT 6 AS x UNION ALL
SELECT 8 AS x UNION ALL
SELECT 10 AS x UNION ALL
SELECT 11 AS x
)
SELECT num
FROM (SELECT x, LEAD(x) OVER(ORDER BY x) AS next_x FROM YourTable),
UNNEST(GENERATE_ARRAY(x + 1,next_x - 1)) AS num
WHERE next_x - x > 1
ORDER BY x