복붙노트

[SQL] MySQL의에서 ROW_NUMBER ()

SQL

MySQL의에서 ROW_NUMBER ()

SQL 서버 기능 ROW_NUMBER를 복제 할 MySQL의에서 좋은 방법은 ()이 있습니까?

예를 들면 :

SELECT 
    col1, col2, 
    ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col3 DESC) AS intRow
FROM Table1

그럼, 예를 들어, 각 (COL1, COL2) 쌍에 대한 가장 높은 COL3로 단일 행을 얻기 위해 1로 제한 intRow에 조건을 추가 할 수 있습니다.

해결법

  1. ==============================

    1.즉 (가 용이해야한다 것처럼 보이기 때문에, 실제로는 가지 아닌) GroupWise에 최대, 가장 일반적으로 묻는 SQL 질문 중 하나입니다.

    즉 (가 용이해야한다 것처럼 보이기 때문에, 실제로는 가지 아닌) GroupWise에 최대, 가장 일반적으로 묻는 SQL 질문 중 하나입니다.

    나는 종종 뚱뚱한 널 자체 조인 :

    SELECT t0.col3
    FROM table AS t0
    LEFT JOIN table AS t1 ON t0.col1=t1.col1 AND t0.col2=t1.col2 AND t1.col3>t0.col3
    WHERE t1.col1 IS NULL;
    

    "일치 COL1과 다른 행, COL2가 높은 COL3를 갖지 않는 테이블의 행을 가져옵니다." (이 작업을 통지합니다 하나 개 이상의 행이 같은 COL1, COL2, COL3이있는 경우 대부분의 다른 GroupWise에 최대 솔루션은 여러 행을 반환합니다. 즉, 문제가 있다면 당신은 어떤 후 처리가 필요할 수 있습니다.)

  2. ==============================

    2.MySQL은 어떤 순위 기능은 없습니다. 당신이 얻을 수있는 가장 가까운 변수를 사용하는 것입니다 :

    MySQL은 어떤 순위 기능은 없습니다. 당신이 얻을 수있는 가장 가까운 변수를 사용하는 것입니다 :

    SELECT t.*, 
           @rownum := @rownum + 1 AS rank
      FROM YOUR_TABLE t, 
           (SELECT @rownum := 0) r
    

    예. 이 오라클라면, 당신은 다음 값으로 피크에 LEAD 기능을 사용할 수 있습니다. 다행히, Quassnoi 당신이 MySQL의에서 구현해야 무엇을위한 로직을 포함한다.

  3. ==============================

    3.난 항상이 패턴 다음 끝. 이 테이블을 감안할 때 :

    난 항상이 패턴 다음 끝. 이 테이블을 감안할 때 :

    +------+------+
    |    i |    j |
    +------+------+
    |    1 |   11 |
    |    1 |   12 |
    |    1 |   13 |
    |    2 |   21 |
    |    2 |   22 |
    |    2 |   23 |
    |    3 |   31 |
    |    3 |   32 |
    |    3 |   33 |
    |    4 |   14 |
    +------+------+
    

    이 결과를 얻을 수 있습니다 :

    +------+------+------------+
    |    i |    j | row_number |
    +------+------+------------+
    |    1 |   11 |          1 |
    |    1 |   12 |          2 |
    |    1 |   13 |          3 |
    |    2 |   21 |          1 |
    |    2 |   22 |          2 |
    |    2 |   23 |          3 |
    |    3 |   31 |          1 |
    |    3 |   32 |          2 |
    |    3 |   33 |          3 |
    |    4 |   14 |          1 |
    +------+------+------------+
    

    정의 된 모든 변수를 필요로하지 않는다이 쿼리를 실행하여 :

    SELECT a.i, a.j, count(*) as row_number FROM test a
    JOIN test b ON a.i = b.i AND a.j >= b.j
    GROUP BY a.i, a.j
    

    희망이 도움이!

  4. ==============================

    4.

    SELECT 
        @i:=@i+1 AS iterator, 
        t.*
    FROM 
        tablename AS t,
        (SELECT @i:=0) AS foo
    
  5. ==============================

    5.이 기사 확인, 어떻게 그것을 모방 SQL의 ROW_NUMBER ()의 파티션과 MySQL의에 의해 보여줍니다. 나는 워드 프레스 구현이 매우 동일한 시나리오에 달렸다. 나는 ROW_NUMBER 필요 ()와이 없었다.

    이 기사 확인, 어떻게 그것을 모방 SQL의 ROW_NUMBER ()의 파티션과 MySQL의에 의해 보여줍니다. 나는 워드 프레스 구현이 매우 동일한 시나리오에 달렸다. 나는 ROW_NUMBER 필요 ()와이 없었다.

    http://www.explodybits.com/2011/11/mysql-row-number/

    기사의 예는 필드에 의해 단일 파티션을 사용하고 있습니다. 추가 필드를 기준으로 분할하는 방법이 뭔가를 할 수 있습니다 :

      SELECT  @row_num := IF(@prev_value=concat_ws('',t.col1,t.col2),@row_num+1,1) AS RowNumber
             ,t.col1 
             ,t.col2
             ,t.Col3
             ,t.col4
             ,@prev_value := concat_ws('',t.col1,t.col2)
        FROM table1 t,
             (SELECT @row_num := 1) x,
             (SELECT @prev_value := '') y
       ORDER BY t.col1,t.col2,t.col3,t.col4 
    

    사용 CONCAT_WS 핸들의를 널 (null). 나는 INT, 날짜 및 VARCHAR를 사용하여 3 개 필드에 대해이 테스트. 도움이 되었기를 바랍니다. 그것은이 쿼리 다운 휴식과 설명으로 문서를 확인하세요.

  6. ==============================

    6.MySQL은 8.0.0에서 이상 당신은 기본적으로 윈도우 기능을 사용할 수 있습니다.

    MySQL은 8.0.0에서 이상 당신은 기본적으로 윈도우 기능을 사용할 수 있습니다.

    MySQL은 8.0에서 1.4이란 무엇인가 새로운 기능 :

    ROW_NUMBER () over_clause :

    데모:

    CREATE TABLE Table1(
      id INT AUTO_INCREMENT PRIMARY KEY, col1 INT,col2 INT, col3 TEXT);
    
    INSERT INTO Table1(col1, col2, col3)
    VALUES (1,1,'a'),(1,1,'b'),(1,1,'c'),
           (2,1,'x'),(2,1,'y'),(2,2,'z');
    
    SELECT 
        col1, col2,col3,
        ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col3 DESC) AS intRow
    FROM Table1;
    

    DB 휘티 d 혀라도

  7. ==============================

    7.또한 자신의 쿼리 코드에 약간의 수정과 MOSTY Mostacho의 솔루션에 대한 투표 것이다 :

    또한 자신의 쿼리 코드에 약간의 수정과 MOSTY Mostacho의 솔루션에 대한 투표 것이다 :

    SELECT a.i, a.j, (
        SELECT count(*) from test b where a.j >= b.j AND a.i = b.i
    ) AS row_number FROM test a
    

    어떤 같은 결과를 줄 것이다 :

    +------+------+------------+
    |    i |    j | row_number |
    +------+------+------------+
    |    1 |   11 |          1 |
    |    1 |   12 |          2 |
    |    1 |   13 |          3 |
    |    2 |   21 |          1 |
    |    2 |   22 |          2 |
    |    2 |   23 |          3 |
    |    3 |   31 |          1 |
    |    3 |   32 |          2 |
    |    3 |   33 |          3 |
    |    4 |   14 |          1 |
    +------+------+------------+
    

    테이블에 대한 :

    +------+------+
    |    i |    j |
    +------+------+
    |    1 |   11 |
    |    1 |   12 |
    |    1 |   13 |
    |    2 |   21 |
    |    2 |   22 |
    |    2 |   23 |
    |    3 |   31 |
    |    3 |   32 |
    |    3 |   33 |
    |    4 |   14 |
    +------+------+
    

    쿼리를 사용하지 않을는 가입 및 GROUP BY 수행하는 유일한 차이와 중첩에 의존하는 대신 선택합니다.

  8. ==============================

    8.나는 함수를 정의합니다 :

    나는 함수를 정의합니다 :

    delimiter $$
    DROP FUNCTION IF EXISTS `getFakeId`$$
    CREATE FUNCTION `getFakeId`() RETURNS int(11)
        DETERMINISTIC
    begin
    return if(@fakeId, @fakeId:=@fakeId+1, @fakeId:=1);
    end$$
    

    그럼 내가 할 수있는 :

    select getFakeId() as id, t.* from table t, (select @fakeId:=0) as t2;
    

    지금 당신은 당신이보기에 가질 수 없습니다 하위 쿼리를 필요가 없습니다.

  9. ==============================

    9.MySQL의에서 ROW_NUMBER에 대한 질의

    MySQL의에서 ROW_NUMBER에 대한 질의

    set @row_number=0;
    select (@row_number := @row_number +1) as num,id,name from sbs
    
  10. ==============================

    10.이 MySQL의에서 어떤 ROWNUM 같은 기능, ROWNUM ()는 없지만 주변의 방법은 다음과 같다 :

    이 MySQL의에서 어떤 ROWNUM 같은 기능, ROWNUM ()는 없지만 주변의 방법은 다음과 같다 :

    select 
          @s:=@s+1 serial_no, 
          tbl.* 
    from my_table tbl, (select @s:=0) as s;
    
  11. ==============================

    11.이 솔루션 나는 최선의이 같은 하위 쿼리를 사용하던 일을 발견 :

    이 솔루션 나는 최선의이 같은 하위 쿼리를 사용하던 일을 발견 :

    SELECT 
        col1, col2, 
        (
            SELECT COUNT(*) 
            FROM Table1
            WHERE col1 = t1.col1
            AND col2 = t1.col2
            AND col3 > t1.col3
        ) AS intRow
    FROM Table1 t1
    

    열 BY 파티션은 '='와 비교 AND로 구분하세요. 열 BY 순서는 '<'또는 '>'및 OR에 의해 분리와 비교 될 것이다.

    나는 조금 비용이 많이 드는 경우에도, 이것은 매우 유연하게 발견했습니다.

  12. ==============================

    12.ROWNUMBER 기능을 모방 할 수 없습니다. 당신은 당신이 기대하는 결과를 얻을 수 있습니다,하지만 당신은 대부분 어떤 단계에서 실망거야. 다음은 MySQL의 문서의 말씀입니다 :

    ROWNUMBER 기능을 모방 할 수 없습니다. 당신은 당신이 기대하는 결과를 얻을 수 있습니다,하지만 당신은 대부분 어떤 단계에서 실망거야. 다음은 MySQL의 문서의 말씀입니다 :

    문안 인사, 게오르기.

  13. ==============================

    13.MariaDB 10.2 RANK (), ROW_NUMBER () 및 기타 여러 가지를 포함하여 "윈도우 기능"을 구현한다 :

    MariaDB 10.2 RANK (), ROW_NUMBER () 및 기타 여러 가지를 포함하여 "윈도우 기능"을 구현한다 :

    https://mariadb.com/kb/en/mariadb/window-functions/

    Percona 라이브 이달의 이야기를 바탕으로, 그들은 합리적으로 잘 최적화되어 있습니다.

    구문은 문제의 코드와 동일하다.

  14. ==============================

    14.난 내이기 때문에 여기 부분 "에 의해 PARTITION의"를 덮고있는 간단한 대답이 표시되지 않습니다 :

    난 내이기 때문에 여기 부분 "에 의해 PARTITION의"를 덮고있는 간단한 대답이 표시되지 않습니다 :

    SELECT
        *
    FROM (
        select
            CASE WHEN @partitionBy_1 = l THEN @row_number:=@row_number+1 ELSE @row_number:=1 END AS i
            , @partitionBy_1:=l AS p
            , t.*
        from (
            select @row_number:=0,@partitionBy_1:=null
        ) as x
        cross join (
            select 1 as n, 'a' as l
            union all
            select 1 as n, 'b' as l    
            union all
            select 2 as n, 'b' as l    
            union all
            select 2 as n, 'a' as l
            union all
            select 3 as n, 'a' as l    
            union all    
            select 3 as n, 'b' as l    
        ) as t
        ORDER BY l, n
    ) AS X
    where i > 1
    
  15. ==============================

    15.A는 답을 보이는 사람도 도움을 늦게 비트 수 있지만 ...

    A는 답을 보이는 사람도 도움을 늦게 비트 수 있지만 ...

    행 사이 / ROW_NUMBER 예 - 어떤 SQL에서 사용할 수 있습니다 재귀 쿼리 :

    WITH data(row_num, some_val) AS 
    (
     SELECT 1 row_num, 1 some_val FROM any_table --dual in Oracle
      UNION ALL
     SELECT row_num+1, some_val+row_num FROM data WHERE row_num < 20 -- any number
    )
    SELECT * FROM data
     WHERE row_num BETWEEN 5 AND 10
    /
    
    ROW_NUM    SOME_VAL
    -------------------
    5           11
    6           16
    7           22
    8           29
    9           37
    10          46
    
  16. ==============================

    16.이 ROW_NUMBER ()와 PARTITION BY MySQL을 달성 할 수 제공하는 동일한 기능을 할 수 있습니다

    이 ROW_NUMBER ()와 PARTITION BY MySQL을 달성 할 수 제공하는 동일한 기능을 할 수 있습니다

    SELECT  @row_num := IF(@prev_value=GENDER,@row_num+1,1) AS RowNumber
           FirstName, 
           Age,
           Gender,
           @prev_value := GENDER
      FROM Person,
          (SELECT @row_num := 1) x,
          (SELECT @prev_value := '') y
      ORDER BY Gender, Age DESC
    
  17. ==============================

    17.나는 Google에서 검색 않았고 마침내 간단한 일반적인 접근 방식은 PINAL 데이브의 기사에서 여기에서 찾을 수 있도록 또한 조금 늦었지만 오늘이 같은 요구를했다 http://blog.sqlauthority.com/2014/03/09/mysql-reset-row 넘버를 위해 각각의 그룹 파티션별로 행수 /

    나는 Google에서 검색 않았고 마침내 간단한 일반적인 접근 방식은 PINAL 데이브의 기사에서 여기에서 찾을 수 있도록 또한 조금 늦었지만 오늘이 같은 요구를했다 http://blog.sqlauthority.com/2014/03/09/mysql-reset-row 넘버를 위해 각각의 그룹 파티션별로 행수 /

    내가 작업 예제로 내 솔루션을 요약 있도록 (물론 내 문제였습니다) 바울의 원래의 질문에 집중하고 싶었다.

    우리는이 개 칼럼을 통해 분할 싶기 때문에 나는 새로운 그룹이 시작되었는지 확인하기 위해 반복하는 동안 SET 변수를 만들 것입니다.

    SELECT col1, col2, col3 FROM (
      SELECT col1, col2, col3,
             @n := CASE WHEN @v = MAKE_SET(3, col1, col2)
                        THEN @n + 1 -- if we are in the same group
                        ELSE 1 -- next group starts so we reset the counter
                    END AS row_number,
             @v := MAKE_SET(3, col1, col2) -- we store the current value for next iteration
        FROM Table1, (SELECT @n := 0, @v := NULL) r -- helper table for iteration with startup values
       ORDER BY col1, col2, col3 DESC -- because we want the row with maximum value
    ) x WHERE row_number = 1 -- and here we select exactly the wanted row from each group
    

    (| 2 3 = 1) MAKE_SET의 첫 번째 매개 변수에서 3 개 수단이 나는 세트의 두 값을 원하는. 물론 우리는 우리가 MAKE_SET 작업을 제거 할 수있는 그룹을 구성하는 두 개 이상의 열이없는 경우. 건설 정확히 동일합니다. 필요에 따라이 나를 위해 노력하고 있습니다. 자신의 명확한 시연 PINAL 데이브에 감사드립니다.

  18. ==============================

    18.이것은 또한 해결책이 될 수 있습니다 :

    이것은 또한 해결책이 될 수 있습니다 :

    SET @row_number = 0;
    
    SELECT 
        (@row_number:=@row_number + 1) AS num, firstName, lastName
    FROM
        employees
    
  19. ==============================

    19.MySQL은 버전 8.0 이상부터 ROW_NUMBER ()를 지원하고있다.

    MySQL은 버전 8.0 이상부터 ROW_NUMBER ()를 지원하고있다.

    당신이 MySQL을 8.0 이상을 사용하는 경우, ROW_NUMBER () 함수를 확인해. 그렇지 않으면, 당신은 에뮬레이션 ROW_NUMBER () 함수가 있습니다.

    ROW_NUMBER ()는 제 1 행에서 시작하여 연속 한 시퀀스 번호를 반환 순위 함수이다.

    이전 버전에 대한,

    SELECT t.*, 
           @rowid := @rowid + 1 AS ROWID
      FROM TABLE t, 
           (SELECT @rowid := 0) dummy;
    
  20. ==============================

    20.중요 : MySQL의 8 +로 업그레이드를 고려하고 정의 및 문서화 ROW_NUMBER () 함수와 기능에 묶여 도랑 된 해킹을 사용하십시오 MySQL의 고대 버전을 제한

    중요 : MySQL의 8 +로 업그레이드를 고려하고 정의 및 문서화 ROW_NUMBER () 함수와 기능에 묶여 도랑 된 해킹을 사용하십시오 MySQL의 고대 버전을 제한

    이제 여기 해킹 중 하나입니다 :

    여기에 대한 대답은 사용 쿼리 변수는 대부분 / 모든 문서를 말한다는 사실 (의역)을 무시하는 것처럼 보인다 :

    그들은 일반적으로 작업을 수행하기 때문에 이와 같이, 그들은 잘못된 답을 휘젓다하는 위험이있다

    select
      (row number variable that uses partition variable),
      (assign partition variable)
    

    이 이제까지 아래에서 위로를 평가하는 경우, 행 번호가 작동이 중지됩니다 (파티션)

    그래서 우리는 실행의 보장하기 위해 뭔가를 사용해야합니다. 언제 CASE를 입력 :

    SELECT
      t.*, 
      @r := CASE 
        WHEN col = @prevcol THEN @r + 1 
        WHEN (@prevcol := col) = null THEN null
        ELSE 1 END AS rn
    FROM
      t, 
      (SELECT @r := 0, @prevcol := null) x
    ORDER BY col
    

    개요 LD으로 prevcol의 할당의 순서는 중요합니다 - prevcol은 우리가 현재 행 (그렇지 않으면 현재 행의 COL 값이 아닌 이전 행의 COL 값이 될 것이다) 사이의 값을 할당하기 전에 현재 행의 값과 비교되어야한다 .

    여기에 방법이 적합 함께입니다 :

    우리는이 곳 상황에 도착 :

    SELECT
      t.*, 
      ROW_NUMBER() OVER(PARTITION BY pcol1, pcol2, ... pcolX ORDER BY ocol1, ocol2, ... ocolX) rn
    FROM
      t
    

    일반적인 형식은 다음과 같습니다

    SELECT
      t.*, 
      @r := CASE 
        WHEN col1 = @pcol1 AND col2 = @pcol2 AND ... AND colX = @pcolX THEN @r + 1 
        WHEN (@pcol1 := pcol1) = null OR (@pcol2 := col2) = null OR ... OR (@pcolX := colX) = null THEN null
        ELSE 1 
      END AS rn
    FROM
      t, 
      (SELECT @r := 0, @pcol1 := null, @pcol2 := null, ..., @pcolX := null) x
    ORDER BY pcol1, pcol2, ..., pcolX, ocol1, ocol2, ..., ocolX
    

    각주 :

  21. ==============================

    21.이것은 가장 강력한 해결책이 아니다 -하지만 당신은 단지 몇 가지 값 필드에 파티션 순위를 만들기 위해 찾고 있다면, 그것은 논리는 많은 변수 당신이 필요로 한 때 몇몇 케이스를 사용하는 unwieldily하지 않을 수 있습니다.

    이것은 가장 강력한 해결책이 아니다 -하지만 당신은 단지 몇 가지 값 필드에 파티션 순위를 만들기 위해 찾고 있다면, 그것은 논리는 많은 변수 당신이 필요로 한 때 몇몇 케이스를 사용하는 unwieldily하지 않을 수 있습니다.

    이런 식으로 뭔가 과거에 나를 위해 일했다 :

    SELECT t.*, 
       CASE WHEN <partition_field> = @rownum1 := @rownum1 + 1 
         WHEN <partition_field> = @rownum2 := @rownum2 + 1 
         ...
         END AS rank
    FROM YOUR_TABLE t, 
       (SELECT @rownum1 := 0) r1, (SELECT @rownum2 := 0) r2
    ORDER BY <rank_order_by_field>
    ;
    

    말이 희망 / 데 도움이!

  22. ==============================

    22.우리는 더 이상의 열이있을 때 완벽하게 나를 위해이 작품은 ROWNUMBER을 만들 수 있습니다. 이 경우 두 열의.

    우리는 더 이상의 열이있을 때 완벽하게 나를 위해이 작품은 ROWNUMBER을 만들 수 있습니다. 이 경우 두 열의.

    SELECT @row_num := IF(@prev_value= concat(`Fk_Business_Unit_Code`,`NetIQ_Job_Code`), @row_num+1, 1) AS RowNumber, 
        `Fk_Business_Unit_Code`,   
        `NetIQ_Job_Code`,  
        `Supervisor_Name`,  
        @prev_value := concat(`Fk_Business_Unit_Code`,`NetIQ_Job_Code`)  
    FROM (SELECT DISTINCT `Fk_Business_Unit_Code`,`NetIQ_Job_Code`,`Supervisor_Name`         
          FROM Employee    
          ORDER BY `Fk_Business_Unit_Code`, `NetIQ_Job_Code`, `Supervisor_Name` DESC) z,  
    (SELECT @row_num := 1) x,  
    (SELECT @prev_value := '') y  
    ORDER BY `Fk_Business_Unit_Code`, `NetIQ_Job_Code`,`Supervisor_Name` DESC
    
  23. ==============================

    23.

    set @i = 1;  
    INSERT INTO ARG_VALUE_LOOKUP(ARG_VALUE_LOOKUP_ID,ARGUMENT_NAME,VALUE,DESCRIPTION,UPDATE_TIMESTAMP,UPDATE_USER,VER_NBR,OBJ_ID) 
    select @i:= @i+1 as ARG_VALUE_LOOKUP_ID,ARGUMENT_NAME,VALUE,DESCRIPTION,CURRENT_TIMESTAMP,'admin',1,UUID() 
    FROM TEMP_ARG_VALUE_LOOKUP 
    order by ARGUMENT_NAME;
    
  24. ==============================

    24.

    SELECT 
        col1, col2, 
        count(*) as intRow
    FROM Table1
    GROUP BY col1,col2
    ORDER BY col3 desc
    
  25. from https://stackoverflow.com/questions/1895110/row-number-in-mysql by cc-by-sa and MIT license