0

UNIQUE INT(10) 列を持つ MySQL DB にテーブルがあります。テーブルにはかなりのデータが入力されており、行にはその列に連続していない整数のエントリが含まれています。どの行にもない最小の数値 (または n 個の最小の数値) を取得するクエリを実行したいと思います。

例: テーブルには(1, 2, 3, 5, 7, 8, 10, 12, 15)、列の値を持つ行が含まれています。sql ステートメントは、つまり、含まれていない最低 5 つの値 (4, 6, 9, 11, 13この場合はこれ) を返す必要があります。

これは MySQL で可能ですか?

4

2 に答える 2

4

「数値」テーブルを使用できます (さまざまな操作に便利です)。

CREATE TABLE num
( i UNSIGNED INT NOT NULL
, PRIMARY KEY (i)
) ;

INSERT INTO num (i)
VALUES
  (1), (2), ..., (1000000) ;

それで:

SELECT 
    num.i
FROM 
        num
    LEFT JOIN
        tableX AS t
            ON num.i = t.columnX
WHERE 
    t.columnX IS NULL
ORDER BY
    num.i
LIMIT 5

また:

SELECT 
    num.i
FROM 
    num
WHERE 
    NOT EXISTS 
    ( SELECT *
      FROM tableX AS t
      WHERE num.i = t.columnX
    )
ORDER BY
    num.i
LIMIT 5

補助テーブルを使用しない別のアプローチは、MySQL 変数を使用することです。SQL-Fiddle、test-2 でテストできます。出力は前のものと同じではありません (実行できることを示すためだけです)。

SELECT start_id, end_id
FROM 
  ( SELECT 
        IF( t.columnX <> @id, @id, NULL)       AS start_id
      , IF( t.columnX <> @id, t.columnX-1, NULL) AS end_id
      , @rows := @rows + (t.columnX - @id)     AS r
      , @id := t.columnX + 1                   AS running_id
    FROM 
            tableX AS t
        CROSS JOIN  
            ( SELECT @rows := 0
                   , @id := 1
            ) AS dummy
    WHERE
        @rows < 5
    ORDER BY
        t.columnX
    ) AS tmp
WHERE
    start_id IS NOT NULL
于 2012-04-11T10:09:13.670 に答える
2

これは機能しますが、かなり非効率的だと思います。ただし、追加のテーブルは必要ありません ( (2^31-1)*4/1024^3 = 8GBINT のすべての正の数用のテーブル)。また、必要ではない可能性があるため、なぜこれが必要なのかを確認することをお勧めします。

また、範囲の開始と終了を返しますが、その範囲内のすべての数値ではありません。(たとえば、数字が 1 と 5 の場合、{0,2,4,6} が返されます)

SELECT (t.num-1) AS bound FROM t
    WHERE t.num-1 NOT IN (SELECT t.num FROM t)
UNION
SELECT (t.num+1) AS bound FROM t
    WHERE t.num+1 NOT IN (SELECT t.num FROM t) 

私が言ったように、これはかなり非効率的で、JOIN の方が速いかもしれませんが、ベンチマークが必要です。

SELECT (t.num-1) AS bound FROM t
    LEFT JOIN t AS u ON t.num-1 = u.num
    WHERE u.num IS NULL
UNION
SELECT (t.num+1) AS bound FROM t
    LEFT JOIN t AS u ON t.num+1 = u.num
    WHERE u.num IS NULL
于 2012-04-11T10:33:56.997 に答える