복붙노트

[SQL] 이 행의 위치를 ​​포함하도록 업데이트 칼럼

SQL

이 행의 위치를 ​​포함하도록 업데이트 칼럼

이 콘텐츠 테이블 :

ContentID | CategoryID | Position | Other1 | Other2
===================================================
1         | 1          | NULL     | abcd   | efgh
2         | 1          | NULL     | abcd   | efgh
3         | 1          | NULL     | abcd   | efgh
4         | 2          | NULL     | abcd   | efgh
5         | 2          | NULL     | abcd   | efgh
6         | 2          | NULL     | abcd   | efgh

다음은 내가 실행됩니다 쿼리 있습니다 :

SELECT ContentID FROM content WHERE CategoryID = 1 ORDER BY Position
SELECT ContentID FROM content WHERE CategoryID = 2 ORDER BY Position

지금은, 아래로 이동, 이동 구현하는 콘텐츠를 아래 기능 상단과 이동로 이동합니다. 할 수있는 모든 I 필요 숫자와 위치 열을 채우는 것입니다 :

ContentID | CategoryID | Position
=================================
1         | 1          | 1
2         | 1          | 2
3         | 1          | 3
4         | 2          | 1
5         | 2          | 2
6         | 2          | 3

그것은 MySQL은 단일 쿼리를 통해이를 달성 할 수 있습니까? 뭔가 같은 :

UPDATE content
SET Position = <ROW_NUMBER>
WHERE CategoryID = 1
ORDER BY Position

UPDATE content
SET Position = <ROW_NUMBER>
WHERE CategoryID = 2
ORDER BY Position

해결법

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

    1.이 작업을해야합니다

    이 작업을해야합니다

    update 
    content,
    (
      select 
      @row_number:=ifnull(@row_number, 0)+1 as new_position,
      ContentID 
      from content
      where CategoryID=1
      order by position
    ) as table_position
    set position=table_position.new_position
    where table_position.ContentID=content.ContentID;
    

    하지만이 설정되지 않은 사용자 정의 변수에 먼저 적용하는 것을 선호

    set @row_number:=0;
    

    이 같은 하나 개의 문장에서 그것을 할 수

    update 
    content,
    (
      select 
      @row_number:=ifnull(@row_number, 0)+1 as new_position,
      ContentID 
      from content
      where CategoryID=1
      order by position
    ) as table_position,
    (
      select @row_number:=0
    ) as rowNumberInit
    set position=table_position.new_position
    where table_position.ContentID=content.ContentID;
    
  2. ==============================

    2.여기에 나를 위해 일한 솔루션 (희망이 사람을 도움)입니다 :

    여기에 나를 위해 일한 솔루션 (희망이 사람을 도움)입니다 :

    -- The following query re-populates the "Position" column with sequential numbers so that:
    -- a) sequence is reset to 1 for each "group"
    -- b) sequence is based on row number relative to each group depending on how ORDER BY is specified
    -- c) sequence does not disturb the original order but
    -- c.a) fixes NULLs so that they are moved to top
    -- c.b) fixes duplicate position values depending on how ORDER BY is specified
    
    -- ContentID is the primary key
    -- CategoryID is a foreign key
    -- Position column contains relative position of a record
    
    SET @current_group = NULL;
    SET @current_count = NULL;
    
    UPDATE 
    content
    SET Position = CASE
        WHEN @current_group = CategoryID THEN @current_count := @current_count + 1
        WHEN @current_group := CategoryID THEN @current_count := 1
    END
    ORDER BY CategoryID, Position -- <Column 3>, <Column 4>, ...
    
  3. ==============================

    3.나는 당신이 테이블에 몇 가지 작업을 수행 할 때 모든 시간을 추가 쿼리를 실행하는 것은 매우 지루한 될 것이라고 생각합니다. 난 당신이 테이블에 / 업데이트 무언가를 삽입 할 때마다 발생시키는 트리거를 만들 것입니다.

    나는 당신이 테이블에 몇 가지 작업을 수행 할 때 모든 시간을 추가 쿼리를 실행하는 것은 매우 지루한 될 것이라고 생각합니다. 난 당신이 테이블에 / 업데이트 무언가를 삽입 할 때마다 발생시키는 트리거를 만들 것입니다.

    귀하의 경우, BEFORE UPDATE와 BEFORE INSERT 트리거는 것이 바람직 할 것이다. 당신은 또한 etntry의 삭제 후 청결을 유지하려는 경우, AFTER DELETE 트리거를 추가합니다.

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

    4.머리 글자:

    머리 글자:

    UPDATE content as uc 
    SET Position = (
        SELECT count(*) 
        FROM content as sc 
        WHERE sc.CategoryId = uc.CategoryId AND sc.Position is not null)
    WHERE uc.Position is null
    ORDER BY uc.ContentId
    

    삽입하기 전에 :

    UPDATE content
    SET Position = Position+1
    WHERE Position >= newPos AND CategoryId = newCat
    
  5. from https://stackoverflow.com/questions/4632696/updating-column-so-that-it-contains-the-row-position by cc-by-sa and MIT license