mysql에서 모든 n 번째 행을 어떻게 선택합니까?


79

꺾은 선형 차트를 만들기 위해 가져와야하는 일련의 값이 데이터베이스에 있습니다. 고해상도가 필요하지 않기 때문에 데이터베이스에서 5 번째 행을 모두 선택하여 데이터를 다시 샘플링하고 싶습니다.

답변:


84
SELECT * 
FROM ( 
    SELECT 
        @row := @row +1 AS rownum, [column name] 
    FROM ( 
        SELECT @row :=0) r, [table name] 
    ) ranked 
WHERE rownum % [n] = 1 

5
누군가 이것이 어떻게 작동하는지 더 많은 정보를 제공 할 수 있습니까? 예를 들어 질문은 매 5 번째 행에 대해 물었고 대답에 5에 대한 언급이 없습니다.
Crazometer 2015

4
@Crazometer [n]는 쿼리에서 5로 대체 하여 5 번째 행마다 가져옵니다.
Benjamin Manns

이것을 확장하기 위해, 예를 들어 첫 번째 행이 아니라 두 번째 행으로 시작하고 싶지 않다면 어떻게해야할까요?
HPWD

당신은 대체 할 @HPWD @row :=0@row :=2
Binar 웹

@BinarWeb 아니, 당신은 바꿀 것 = 1= 2
ysth

55

mod 5를 시도 하여 ID가 ​​5의 배수 인 행을 가져올 수 있습니다 (순차적 인 일종의 ID 열이 있다고 가정).

select * from table where table.id mod 5 = 0;

19
또한 삭제 또는 롤백으로 인해 시퀀스에 간격이 없다고 가정합니다.
Bill Karwin

3
이것은 대부분의 경우 작동하지만 삭제 된 행은 고려하지 않습니다.
Corban Brook

2
간단하고 :-) 몇 가지 테스트를위한 화려한
리 카드 Liljeberg

1
선택 항목이 모든 데이터를 검색하는 경우 의미가 있습니다. 선택 항목에 추가 기준이있는 경우 검색 할 데이터 (있는 경우)를 말하기가 어렵습니다.
j_kubik 2015

24

MySQL을 사용한다고 말 했으므로 사용자 변수 를 사용하여 연속 행 번호 매기기를 만들 수 있습니다 . 그래도 파생 테이블 (서브 쿼리)에 넣어야합니다.

SET @x := 0;
SELECT *
FROM (SELECT (@x:=@x+1) AS x, mt.* FROM mytable mt ORDER BY RAND()) t
WHERE x MOD 5 = 0;

ORDER BY RAND()순서가 지정되지 않은 테이블의 모든 다섯 번째 행이 매번 샘플에 있도록 허용하는 대신 의사 난수 샘플링을 얻기 위해 추가 했습니다.


익명 사용자가이 파일을로 변경 x MOD 5 = 0하기 위해 편집하려고 했습니다 x MOD 5 = 1. 내 원본으로 다시 변경했습니다.

레코드의 경우 해당 조건에서 0에서 4 사이의 값을 사용할 수 있으며 한 값을 다른 값보다 선호 할 이유가 없습니다.


나는 이것에 대한 내 대답을 업데이트하고 있었고 당신은 나를 이겼습니다! 좋은 생각입니다.
Josh Stodola

1
불행하게도, 적어도 × 100에서 여러 항목으로 작업 할 경우에 실행 다운이 느려
phil294

10
SET @a = 0;
SELECT * FROM t where (@a := @a + 1) % 2 = 0;

이것은 행의 병렬 처리를 위해 임의의 읽기 전용 테이블을 분할하는 데 적합하며 구문은 읽고 이해하기가 매우 쉽습니다. 각 행이 한 번만 반환되도록 기본 키 열에 ORDER BY를 추가하기 만하면됩니다.
humbads

2

나는 이와 같은 것을 찾고 있었다. Taylor와 Bill의 대답은 제가 그들의 아이디어를 개선하도록 이끌었습니다.

data1 테이블에는 read_date 필드가 있으며, read_date 범위로 제한되는 쿼리에서 모든 2d 레코드를 선택하려는 값은 파생 테이블의 이름은 임의적이며 여기서는 DT라고합니다.

질문:

 SET @row := 0;
  SELECT * FROM  ( SELECT @row := @row +1 AS rownum, read_date, value  FROM data1  
  WHERE  read_date>= 1279771200 AND read_date <= 1281844740 ) as DT WHERE MOD(rownum,2)=0

감사합니다. 이걸 찾고 있었어요. 저장 프로 시저에 대한 로그 테이블의 특정 열이 매번 동일한 값을 갖는지 어떻게 든 확인해야했습니다. 'proc starting', 'proc ending'과 같습니다. 모든 것이 정상이면 아래의 sql은 1이됩니다. SET @row := 0; SELECT count(distinct Message) FROM ( SELECT @row := @row +1 AS rownum, Message FROM operations.EventLog WHERE LogTime > now() - interval 6 hour and ProcedureName = 'Do_CDR' ) as DT WHERE MOD(rownum,2)=0;
eigil

1

이 쿼리를 사용할 수 있습니다.

set @n=2; <!-- nth row -->
select * from (SELECT t.*, 
       @rowid := @rowid + 1 AS ID
  FROM TABLE t, 
       (SELECT @rowid := 0) dummy) A where A.ID mod @n = 0;

또는 nn 번째 값으로 바꿀 수 있습니다.


1
SELECT *
FROM ( 
    SELECT @row := @row +1 AS rownum, posts.*
    FROM (
        SELECT @row :=0) r, posts
    ) ranked
WHERE rownum %3 = 1

게시물은 내 테이블입니다.


1

MariaDB 10.2, MySQL 8 이상을 사용하는 경우이 작업을 더 효율적으로 수행 할 수 있으며 공통 테이블 표현식창 함수를 사용하여 더 명확하게 생각 합니다 .

WITH ordering AS (
  SELECT ROW_NUMBER() OVER (ORDER BY name) AS n, example.* 
    FROM example ORDER BY name
)
SELECT * FROM ordering WHERE MOD(n, 5) = 0;

개념적으로 이것은 필드 example별로 정렬 된 테이블 의 내용으로 임시 테이블을 만들고 행 번호 name라는 추가 필드를 추가 한 n다음 정확히 5로 나눌 수있는 숫자가있는 행, 즉 매 5 번째 행만 가져옵니다. 실제로 데이터베이스 엔진은 종종 이보다 더 잘 최적화 할 수 있습니다. 그러나 더 이상 최적화하지 않더라도 이전 버전의 MySQL에서했던 것처럼 반복적으로 사용자 변수를 사용하는 것보다 더 명확하다고 생각합니다 .


0

결과 집합에 행 번호가 필요하지 않은 경우 쿼리를 단순화 할 수 있습니다.

SELECT 
    [column name] 
FROM
    (SELECT @row:=0) temp, 
    [table name] 
WHERE (@row:=@row + 1) % [n] = 1 

다음 자리 표시자를 바꿉니다.

  1. [column name]가져와야하는 열 목록으로 바꿉니다 .
  2. [table name]테이블 이름으로 바꿉니다 .
  3. [n]숫자로 바꿉니다 . 예를 들어 5 번째 행마다 필요한 경우 5로 바꿉니다.

감사합니다. 가깝지만 이렇게하는 것이 좋습니다 : select name from (SELECT @row : =-1) temp, t where (@row : = @ row + 1) % 1 = 0; 이것은 두 가지 장점이 있습니다. 첫째, n에 관계없이 항상 첫 번째 행을 얻고 두 번째로 n = 1로 만들면 없음이 아닌 모든 값을 얻습니다. (두 가지 변경 : -1 연속 : =-1 및 n = 0 대신 n = 1)
Bruce
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.