次の表があります。
CREATE TABLE dummy (
thousand INT(10) UNSIGNED,
UNIQUE(thousand)
);
1 から 100 万までの正の整数を 1000 番目ごとに挿入するために使用できる SQL 構文はありますか? これはphpで実現できますが、ストアドプロシージャを使用せずにこれが可能かどうか疑問に思っていました.
thousand
1
1001
2001
3001
4001
...
998001
999001
これは、@ sergeBelovソリューションと同様に、私が通常これらの種類の問題に使用するトリックです。
アンカーテーブルと一時テーブルを作成し、次のように0から9までの値を入力します。
CREATE TABLE TEMP (Digit int);
INSERT INTO Temp VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
次に、これを行うことができます:
INSERT INTO dummy(thousand)
SELECT 1 + (id - 1) * 1000 AS n
FROM
(
SELECT t3.digit * 100 + t2.digit * 10 + t1.digit + 1 AS id
FROM TEMP AS t1
CROSS JOIN TEMP AS t2
CROSS JOIN TEMP AS t3
) t;
1, 1001, 2001, ... , 998001, 999001
あなたが探しているシーケンス番号( )1000の用語は、彼らが等差数列と呼んでいるものであり、あなたの場合、nth
シーケンス(an
)の用語は次のように与えられます。
A + (n - 1) * d
In you sequence: a = 1, d = 1000
ここA
で、はシーケンスの最初の項、nは項、dは各2つの項の差です(2つの連続する項ごとに同じです)。
サブクエリ:
SELECT t3.digit * 100 + t2.digit * 10 + t1.digit + 1 AS id
FROM TEMP AS t1
CROSS JOIN TEMP AS t2
CROSS JOIN TEMP AS t3;
1から1000(シーケンス内の用語の総数)までの番号のリストを生成し1 + (id - 1) * 1000
ます。その後、外側の選択でこれらの番号からシーケンス内の各用語を取得します。
insert into dummy
( thousand )
select
PreQuery.thousand
from
( select
@sqlvar thousand,
@sqlvar := @sqlvar + 1000
from
AnyTableWithAtLeast1000Records,
( select @sqlvar := 1 ) sqlvars
limit 1000 ) PreQuery
select ステートメントから挿入できます。MySQL 変数を使用して、1 から始めます。次に、行を生成するためだけに、システム内の 1000 (またはそれ以上) のレコードを持つテーブルに結合します。そのようなテーブルから実際の列を取得していなくても、レコードの位置に必要なだけです。次に、@sqlvar は 1 から始まり、千という名前の列に返されます。次に、「AnyTable...」の次のレコードのためにすぐに 1000 を追加します。
残念ながら、mysql は特別な SQL 関数でこれをサポートしていません。
テーブルにデータを入力する必要がありますが、これはそれほど大したことではありません。1000 行しかありません。
ユニオンを使って一時テーブルをハックすることもできますが、それは洗練されたものではありません。テーブルを使用することもできます。
他のデータベースは、たとえば postgres のgenerate_series()
機能を使用してそれをサポートしていますが、それはほとんど慰めにはなりません。
1
補足として、このような場合に、テーブルに連続した数字から大きな数字までの
数字を入力すると便利な場合がよくありますselect 1000 * num from numbers where num <= 1000
。
1つのステートメント クエリの場合、つまり、追加のテーブルとサポート ステートメントを導入しない場合、「疑似」SQL でこのアプローチを使用します。
SELECT (D1.Digit + D2.Digit + D3.Digit)* 1000 + 1
FROM
(
SELECT 0 AS Digit UNION ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9
) AS D1
CROSS JOIN
(
SELECT 0 AS Digit UNION ALL
SELECT 10 UNION ALL
SELECT 20 UNION ALL
SELECT 30 UNION ALL
SELECT 40 UNION ALL
SELECT 50 UNION ALL
SELECT 60 UNION ALL
SELECT 70 UNION ALL
SELECT 80 UNION ALL
SELECT 90
) AS D2
CROSS JOIN
(
SELECT 0 AS Digit UNION ALL
SELECT 100 UNION ALL
SELECT 200 UNION ALL
SELECT 300 UNION ALL
SELECT 400 UNION ALL
SELECT 500 UNION ALL
SELECT 600 UNION ALL
SELECT 700 UNION ALL
SELECT 800 UNION ALL
SELECT 900
) AS D3
WHERE ((D1.Digit + D2.Digit + D3.Digit)* 1000 + 1) < 1000000
100% 確実ではありませんが、mysql で問題なく動作するか、マイナーな変更が必要になる可能性があります。
クエリの一部を再利用できる場合、たとえば SQL Server では、次のように記述します。
WITH Digits AS
(
SELECT 0 AS Digit UNION ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9
)
SELECT (D1.Digit + D2.Digit + D3.Digit)* 1000 + 1
FROM (SELECT Digit FROM Digits) AS D1
CROSS JOIN (SELECT Digit * 10 AS Digit FROM Digits) AS D2
CROSS JOIN (SELECT Digit * 100 AS Digit FROM Digits) AS D3
WHERE ((D1.Digit + D2.Digit + D3.Digit)* 1000 + 1) < 1000000
乗算が発生する場所に注意してください。結果の式ではなく、サブクエリで乗算する方が効率的かもしれません。