MySQL에서 정수 시퀀스 생성
"/result-set/"를 /result-set/"을.n
로로 합니다.m
않고 수 있는 ?테이블을 만들지 않고 그것을 얻을 수 있는 간단한 방법이 있나요?
(그런데 그런 종류의 구조를 '메타 쿼리'라고 부릅니까?)
m-n
1000 미만
나는 이 해결책을 웹에서 찾았다.
SET @row := 0;
SELECT @row := @row + 1 as row, t.*
FROM some_table t, (SELECT @row := 0) r
단일 쿼리가 빠르고 원하는 대로 수행됩니다.복잡한 쿼리에서 찾은 "선택 항목"을 "번호 매기기" 할 수 있습니다.이러한 쿼리는 1부터 시작하여 각 행마다 1씩 증가합니다.
것 같습니다.첫 시작 해 주세요.이치노@row
한계
BTW: 저는 "r"이 정말 필요하지 않다고 생각합니다.
ddsp
다음은 1을 반환합니다.10000으로 그리 느리지 않다
SELECT @row := @row + 1 AS row FROM
(select 0 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) t,
(select 0 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) t2,
(select 0 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) t3,
(select 0 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) t4,
(SELECT @row:=0) numbers;
MySQL의 MariaDB 포크를 사용하는 경우 엔진은 번호 시퀀스를 직접 생성할 수 있습니다.가상(가짜) 열 테이블을 사용하여 이를 수행합니다.
예를 들어 1에서 1000까지의 정수 시퀀스를 생성하려면 다음과 같이 하십시오.
SELECT seq FROM seq_1_to_1000;
0 ~ 11 의 경우는, 이것을 실시합니다.
SELECT seq FROM seq_0_to_11;
오늘부터 일주일 동안 연속된 DATE 값의 경우 이 작업을 수행합니다.
SELECT FROM_DAYS(seq + TO_DAYS(CURDATE)) dateseq FROM seq_0_to_6
★★★★★★★★★★DATE
'은 이렇게 2010-01-01-01.'
SELECT FROM_DAYS(seq + TO_DAYS('2010-01-01')) dateseq
FROM seq_0_to_3800
WHERE FROM_DAYS(seq + TO_DAYS('2010-01-01')) < '2010-01-01' + INTERVAL 10 YEAR
혹시 MariaDB를 사용하고 있지 않다면 검토해 주십시오.
이거 먹어봐..mysql version 8.0에서는 동작합니다.필요한 범위에 따라 아래 쿼리를 수정할 수 있습니다.
WITH recursive numbers AS (
select 0 as Date
union all
select Date + 1
from numbers
where Date < 10)
select * from numbers;
게시물에 기재되어 있는 표를 작성하지 않고 네.
MySQL에 시퀀스 번호 생성기(CREATE SEQUENCE)가 없습니다.가장 가까운 것은AUTO_INCREMENT
테이블 구축에 도움이 됩니다.
1 ~ 100.000 범위의 번호 시퀀스:
SELECT e*10000+d*1000+c*100+b*10+a n FROM
(select 0 a 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) t1,
(select 0 b 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) t2,
(select 0 c 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) t3,
(select 0 d 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) t4,
(select 0 e 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) t5
order by 1
몇 가지 번호가 잘못된 경우 다음과 같이 감사할 때 사용합니다.
select * from (
select 121 id
union all select 123
union all select 125
union all select 126
union all select 127
union all select 128
union all select 129
) a
right join (
SELECT e*10000+d*1000+c*100+b*10+a n FROM
(select 0 a 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) t1,
(select 0 b 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) t2,
(select 0 c 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) t3,
(select 0 d 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) t4,
(select 0 e 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) t5
order by 1
) seq on seq.n=a.id
where seq.n between 121 and 129
and id is null
그 결과 121과 129 사이의 시퀀스 번호 122와 124의 갭이 발생합니다.
id n
---- ---
null 122
null 124
누군가 도움이 될지도 몰라!
단일 쿼리에서 값 범위를 가져오는 방법이 있지만 약간 느립니다.캐시 테이블을 사용하여 속도를 높일 수 있습니다.
모든 BOUAL 값의 범위를 가진 선택을 원한다고 가정합니다.
SELECT 0 as b UNION SELECT 1 as b;
우리는 전망을 만들 수 있다.
CREATE VIEW ViewBoolean AS SELECT 0 as b UNION SELECT 1 as b;
그러면 다음 방법으로 바이트를 수행할 수 있습니다.
CREATE VIEW ViewByteValues AS
SELECT b0.b + b1.b*2 + b2.b*4 + b3.b*8 + b4.b*16 + b5.b*32 + b6.b*64 + b7.b*128 as v FROM
ViewBoolean b0,ViewBoolean b1,ViewBoolean b2,ViewBoolean b3,ViewBoolean b4,ViewBoolean b5,ViewBoolean b6,ViewBoolean b7;
그럼 넌 할 수 있어
CREATE VIEW ViewInt16 AS
SELECT b0.v + b1.v*256 as v FROM
ViewByteValues b0,ViewByteValues b1;
그럼 넌 할 수 있어
SELECT v+MIN as x FROM ViewInt16 WHERE v<MAX-MIN;
이 속도를 높이기 위해 바이트 값의 자동 계산을 건너뛰고 자신을 만들었습니다.
CREATE VIEW ViewByteValues AS
SELECT 0 as v UNION SELECT 1 as v UNION SELECT ...
...
...254 as v UNION SELECT 255 as v;
날짜 범위가 필요하면 할 수 있습니다.
SELECT DATE_ADD('start_date',v) as day FROM ViewInt16 WHERE v<NumDays;
또는
SELECT DATE_ADD('start_date',v) as day FROM ViewInt16 WHERE day<'end_date';
조금 더 빠른 MAKEDATE 기능으로 이 속도를 높일 수 있습니다.
SELECT MAKEDATE(start_year,1+v) as day FRON ViewInt16 WHERE day>'start_date' AND day<'end_date';
이 트릭은 매우 느리고 미리 정의된 도메인(예: int16 = 0...65536 )에서 FINIT 시퀀스만 생성할 수 있습니다.
MySQL에 계산을 정지할 곳을 암시함으로써 쿼리를 조금 더 빠르게 수정할 수 있을 것입니다.(WHERE 절 등의 대신 ON 절을 사용합니다.)
예를 들어 다음과 같습니다.
SELECT MIN + (b0.v + b1.v*256 + b2.v*65536 + b3.v*16777216) FROM
ViewByteValues b0,
ViewByteValues b1,
ViewByteValues b2,
ViewByteValues b3
WHERE (b0.v + b1.v*256 + b2.v*65536 + b3.v*16777216) < MAX-MIN;
SQL Server를 몇 시간 동안 계속 사용할 수 있습니다.
하지만
SELECT MIN + (b0.v + b1.v*256 + b2.v*65536 + b3.v*16777216) FROM
ViewByteValues b0
INNER JOIN ViewByteValues b1 ON (b1.v*256<(MAX-MIN))
INNER JOIN ViewByteValues b2 ON (b2.v*65536<(MAX-MIN))
INNER JOIN ViewByteValues b3 ON (b3.v*16777216<(MAX-MIN)
WHERE (b0.v + b1.v*256 + b2.v*65536 + b3.v*16777216) < (MAX-MIN);
MAX-MIN이 LIMIT 1,30으로 결과를 제한하면 MAX-MIN이 큰 경우에도 카운트(*)는 시간이 오래 걸리고 MAX-MIN이 10만보다 클 때 ORDER BY를 추가하는 실수를 하면 다시 계산하는데 몇 초가 걸립니다.
다음과 같은 작업을 수행할 수 있습니다.
SELECT @rn:=@rn+1 as n
FROM (select @rn:=2)t, `order` rows_1, `order` rows_2 --, rows_n as needed...
LIMIT 4
서 ★★★★★order
행의 이 꽤 큰 에 지나지 않습니다.
편집: 원래 답변이 틀렸습니다.같은 개념의 실제 사례를 제공한 David Poor에게 모든 공로를 돌려야 합니다.
카운터 범위는 1 ~1000 입니다
- 테이블을 생성할 필요가 없습니다.
- 실행 시간 최대 0.0014초
- 뷰로 변환할 수 있다
select tt.row from
(
SELECT cast( concat(t.0,t2.0,t3.0) + 1 As UNSIGNED) as 'row' FROM
(select 0 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) t,
(select 0 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) t2,
(select 0 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) t3
) tt
order by tt.row
Credits: 답변, 답변 아래에 Seth McCauley의 코멘트가 있습니다.
다음을 사용하여 상당히 큰 세트를 구성할 수 있을 것 같습니다.
select 9 colname union all select 10 union all select 11 union all select 12 union all select 13 ...
5300년대 5.0.51a에서 파서 스택 오버플로가 발생했습니다.
다음은 다른 답변에 사용된 기술의 간략한 바이너리 버전입니다.
select ((((((b7.0 << 1 | b6.0) << 1 | b5.0) << 1 | b4.0)
<< 1 | b3.0) << 1 | b2.0) << 1 | b1.0) << 1 | b0.0 as n
from (select 0 union all select 1) as b0,
(select 0 union all select 1) as b1,
(select 0 union all select 1) as b2,
(select 0 union all select 1) as b3,
(select 0 union all select 1) as b4,
(select 0 union all select 1) as b5,
(select 0 union all select 1) as b6,
(select 0 union all select 1) as b7
고유한 단계나 정렬 단계, 문자열에서 숫자로의 변환, 산술 연산이 없으며 각 더미 테이블에는 2줄만 있으므로 매우 빠릅니다.
이 버전은 8개의 "비트"를 사용하기 때문에 0에서 255까지 셀 수 있지만 쉽게 조정할 수 있습니다.
이 쿼리는 0 ~1023 의 숫자를 생성합니다.모든 SQL 데이터베이스 플레이버에서 사용할 수 있습니다.
select
i0.i
+i1.i*2
+i2.i*4
+i3.i*8
+i4.i*16
+i5.i*32
+i6.i*64
+i7.i*128
+i8.i*256
+i9.i*512
as i
from
(select 0 as i union select 1) as i0
cross join (select 0 as i union select 1) as i1
cross join (select 0 as i union select 1) as i2
cross join (select 0 as i union select 1) as i3
cross join (select 0 as i union select 1) as i4
cross join (select 0 as i union select 1) as i5
cross join (select 0 as i union select 1) as i6
cross join (select 0 as i union select 1) as i7
cross join (select 0 as i union select 1) as i8
cross join (select 0 as i union select 1) as i9
가장 간단한 방법은 다음과 같습니다.
SET @seq := 0;
SELECT @seq := FLOOR(@seq + 1) AS sequence, yt.*
FROM your_table yt;
또는 1개의 쿼리에 있습니다.
SELECT @seq := FLOOR(@seq + 1) AS sequence, yt.*
FROM (SELECT @seq := 0) s, your_table yt;
FLOOR()
는 '이러다'를 얻기 위해 합니다.INTEGER
FLOAT
하다. 때로는 그것이 필요하다.
내 대답은 David Poor의 대답에서 영감을 얻었다.고마워요, 데이빗!
m은 얼마나 크니?
다음과 같은 작업을 수행할 수 있습니다.
create table two select null foo union all select null;
create temporary table seq ( foo int primary key auto_increment ) auto_increment=9 select a.foo from two a, two b, two c, two d;
select * from seq where foo <= 23;
여기서 auto_displaces는 n으로 설정되며 where구는 m과 비교되며 2개의 테이블이 반복되는 횟수는 적어도 ceil(log(m-n+1)/log(2)입니다.
(임시 테이블 생성 seq에서 2개를 (null foo union all select null)로 대체하면 비임시 테이블이 생략될 수 있습니다).
경고: 한 번에 한 행씩 숫자를 삽입하면 N개의 명령이 실행됩니다. 여기서 N은 삽입해야 할 행의 수입니다.
임시 테이블을 사용하면 O(log N)로 줄일 수 있습니다(100 ~10699 의 번호 삽입에 대해서는, 이하를 참조해 주세요).
mysql> CREATE TABLE `tmp_keys` (`k` INTEGER UNSIGNED, PRIMARY KEY (`k`));
Query OK, 0 rows affected (0.11 sec)
mysql> INSERT INTO `tmp_keys` VALUES (0),(1),(2),(3),(4),(5),(6),(7);
Query OK, 8 rows affected (0.03 sec)
Records: 8 Duplicates: 0 Warnings: 0
mysql> INSERT INTO `tmp_keys` SELECT k+8 from `tmp_keys`;
Query OK, 8 rows affected (0.02 sec)
Records: 8 Duplicates: 0 Warnings: 0
mysql> INSERT INTO `tmp_keys` SELECT k+16 from `tmp_keys`;
Query OK, 16 rows affected (0.03 sec)
Records: 16 Duplicates: 0 Warnings: 0
mysql> INSERT INTO `tmp_keys` SELECT k+32 from `tmp_keys`;
Query OK, 32 rows affected (0.03 sec)
Records: 32 Duplicates: 0 Warnings: 0
mysql> INSERT INTO `tmp_keys` SELECT k+64 from `tmp_keys`;
Query OK, 64 rows affected (0.03 sec)
Records: 64 Duplicates: 0 Warnings: 0
mysql> INSERT INTO `tmp_keys` SELECT k+128 from `tmp_keys`;
Query OK, 128 rows affected (0.05 sec)
Records: 128 Duplicates: 0 Warnings: 0
mysql> INSERT INTO `tmp_keys` SELECT k+256 from `tmp_keys`;
Query OK, 256 rows affected (0.03 sec)
Records: 256 Duplicates: 0 Warnings: 0
mysql> INSERT INTO `tmp_keys` SELECT k+512 from `tmp_keys`;
Query OK, 512 rows affected (0.11 sec)
Records: 512 Duplicates: 0 Warnings: 0
mysql> INSERT INTO inttable SELECT k+10000 FROM `tmp_keys` WHERE k<700;
Query OK, 700 rows affected (0.16 sec)
Records: 700 Duplicates: 0 Warnings: 0
edit: fyi, 안타깝게도 MySQL 5.0에서는 삽입할 수 없기 때문에 실제 임시 테이블에서는 사용할 수 없습니다(두 임시 테이블 사이를 왔다 갔다 할 수 있습니다).
편집: MEMORY 스토리지 엔진을 사용하여 실제로 "실제" 데이터베이스에서의 데이터 소모를 방지할 수 있습니다.가상 스토리지를 인스턴스화하여 이와 같은 시퀀스를 생성하는 "Numbers" 가상 스토리지 엔진을 개발한 사람이 있는지 궁금합니다.(아, MySQL 이외에서는 휴대 불가)
with t1 as (
select 0 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 ROW_NUMBER() over ()
FROM
t1,
t1 as t2;
원하는 큰 테이블(10의 n제곱)에 대해 t1 테이블의 에일리어스를 계속할 수 있습니다.그런 다음 한계 X를 더해서 끊을 수 있습니다.
Oracle을 사용하는 경우 '파이프라인 기능'을 사용하는 것이 좋습니다.안타깝게도 MySQL에는 이러한 구성이 없습니다.
원하는 숫자의 규모에 따라 두 가지 간단한 방법이 있습니다.단일 쿼리에 필요한 숫자만 임시 테이블에 입력하거나(저장된 프로시저에 의해 입력된 메모리 테이블을 사용하여), 1 ~1,000,000까지 카운트하는 큰 테이블을 전면에 작성하고 그 경계 영역을 선택합니다.
언급URL : https://stackoverflow.com/questions/304461/generate-an-integer-sequence-in-mysql
'programing' 카테고리의 다른 글
코틀린의 정적 초기화 블록 (0) | 2023.02.03 |
---|---|
사전에 키가 있는지 확인하려면 어떻게 해야 하나요? (0) | 2023.02.03 |
제출 시 페이지 새로 고침 중지 (0) | 2023.02.03 |
문자열 형식의 명명된 자리 표시자 (0) | 2023.02.03 |
jQuery 플러그인 확인 - 간단한 사용자 지정 규칙을 만드는 방법 (0) | 2023.02.03 |