복붙노트

[SQL] SQL : 결과 행을 여러 번, 그리고 수 행을 반복

SQL

SQL : 결과 행을 여러 번, 그리고 수 행을 반복

이 같은 결과에 SQL 쿼리를 가지고 :

value | count
------+------
foo   |     1
bar   |     3
baz   |     2

지금은 각 행이 하나가 여러 번 발생보다 더 많이 계산되도록이 확장하려는. 또한 이러한 행 번호 될 필요가있다. 그래서에게 내가 얻을 것이다 :

value | count | index
------+-------+------
foo   |     1 |     1
bar   |     3 |     1
bar   |     3 |     2
bar   |     3 |     3
baz   |     2 |     1
baz   |     2 |     2

나는 모든 주요 데이터베이스 (오라클, SQL 서버, MySQL은, PostgreSQL을, 어쩌면 더)에이 일을해야한다. 다른 데이터베이스에서 작동하는 솔루션이 이상적 일 것이나, 그래서 그것이 데이터베이스에 작동하도록하는 영리한 방법을 부탁드립니다.

해결법

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

    1.MySQL을 들어, 뷰를 통해 이루어집니다 가난한 사람의 generate_series를 사용합니다. MySQL은 어떤 CTE 기능이없는 빅 4 중 유일한 RDBMS입니다.

    MySQL을 들어, 뷰를 통해 이루어집니다 가난한 사람의 generate_series를 사용합니다. MySQL은 어떤 CTE 기능이없는 빅 4 중 유일한 RDBMS입니다.

    사실 당신은 지원이 볼 것을 데이터베이스에이 기술을 사용할 수 있습니다. 즉, 거의 모든 데이터베이스 그래서

    발전기 기술은 여기에 출처 : http://use-the-index-luke.com/blog/2011-07-30/mysql-row-generator#mysql_generator_code

    우리가 만든 약간만 수정은 우리가 비트를 대체 할 것입니다 (이동 왼쪽 및 비트 OR)는 각각 단순한 곱셈과 또한 원래 기술에서 기술; 는 SQL Server 및 Oracle과 같은 연산자를 왼쪽에는 변화가 없습니다.

    이 추상화는 99 % 오라클 제외한 모든 데이터베이스에 대한 작업에 보장; 오라클의 SELECT는 모든 테이블없이 작동하지,이 작업을 수행하기 위해, 하나 개 필요 더미 테이블에서 선택 가능, 오라클은 하나 이미이라고 DUAL 테이블을 제공했다. 데이터베이스 이식성은 헛된 꿈입니다 :-)

    여기 추상화 (이 시나리오에서는 어쨌든 정말 필요하지 않습니다) 비트 연산없는 모든 RDBMS에서 작동 전망 및 기능 뉘앙스의 (우리가 제거 또는 VIEW 만 PostgreSQL을을 만들에 교체가와 MySQL 그들을 지원) 모든 주요 데이터베이스 중.

    오라클주의 : 그냥 각 SELECT 발현 후 DUAL FROM 넣어

    CREATE VIEW generator_16
    AS SELECT 0 n 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   UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL
       SELECT 12  UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL 
       SELECT 15;
    
    CREATE VIEW generator_256
    AS SELECT ( ( hi.n * 16 ) + lo.n ) AS n
         FROM generator_16 lo, generator_16 hi;
    
    CREATE VIEW generator_4k
    AS SELECT ( ( hi.n * 256 ) + lo.n ) AS n
         FROM generator_256 lo, generator_16 hi;
    
    CREATE VIEW generator_64k
    AS SELECT ( ( hi.n * 256 ) + lo.n ) AS n
         FROM generator_256 lo, generator_256 hi;
    
    CREATE VIEW generator_1m
    AS SELECT ( ( hi.n * 65536 ) + lo.n ) AS n
         FROM generator_64k lo, generator_16 hi;
    

    그런 다음이 쿼리를 사용 :

    SELECT t.value, t.cnt, i.n
    FROM tbl t
    JOIN generator_64k i 
    ON i.n between 1 and t.cnt
    order by t.value, i.n
    

    PostgreSQL을 : http://www.sqlfiddle.com/#!1/1541d/1

    오라클 : http://www.sqlfiddle.com/#!4/26c05/1

    SQL 서버 : http://www.sqlfiddle.com/#!6/84bee/1

    MySQL은 : http://www.sqlfiddle.com/#!2/78f5b/1

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

    2.당신은 숫자 테이블을 사용할 수 있습니다

    당신은 숫자 테이블을 사용할 수 있습니다

    SELECT value, count, number
    FROM table
        JOIN Numbers 
            ON table.count >= Numbers.number
    

    여기 MSSQL을 사용 SQLFiddle은

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

    3.MySQL은이 표준과 기능에 관해서는 이러한 홀드 아웃이야, 정말 데이터베이스 세계의 IE이다.

    MySQL은이 표준과 기능에 관해서는 이러한 홀드 아웃이야, 정말 데이터베이스 세계의 IE이다.

    MySQL을 제외한 모든 주요 RDBMS에서 작동 :

    with 
    -- Please add this on Postgresql:
    -- RECURSIVE
    tbl_populate(value, cnt, ndx) as
    (
      select value, cnt, 1 from tbl
    
      union all
    
      select t.value, t.cnt, tp.ndx + 1
      from tbl t
      join tbl_populate tp 
      on tp.value = t.value  
      and tp.ndx + 1 <= t.cnt
    )
    select * from tbl_populate
    order by cnt, ndx
    

    SQL 서버 : http://www.sqlfiddle.com/#!6/911a9/1

    오라클 : http://www.sqlfiddle.com/#!4/198cd/1

    PostgreSQL을 : http://www.sqlfiddle.com/#!1/0b03d/1

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

    4.당신은 DB에 얽매이지 솔루션을 요구하고 @Justin 당신에게 좋은 하나를 주었다. 당신은 또한 요청

    당신은 DB에 얽매이지 솔루션을 요구하고 @Justin 당신에게 좋은 하나를 주었다. 당신은 또한 요청

    ) (generate_series : PostgreSQL의 하나가

  5. ==============================

    5.번호 테이블을 생성 - 그 정의는 (이 SQL 서버입니다) 플랫폼에 따라 약간 다를 수 있습니다 :

    번호 테이블을 생성 - 그 정의는 (이 SQL 서버입니다) 플랫폼에 따라 약간 다를 수 있습니다 :

    CREATE TABLE Numbers(Number INT PRIMARY KEY);
    
    INSERT Numbers 
    SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY name)
    FROM sys.all_columns;
    

    이제이 온도는 또한 SQL 서버이지만,이 (내가 그래서 테스트 할 수 없습니다를 사용하지 않는 고백하지만) 사용자가 지정한 RDBMS에서 걸쳐 유효해야 조인 구문을 보여줍니다

    DECLARE @foo TABLE(value VARCHAR(32), [count] INT);
    
    INSERT @foo SELECT 'foo', 1
    UNION ALL SELECT 'bar', 3
    UNION ALL SELECT 'baz', 2;
    
    SELECT f.value, f.[count], [index] = n.Number
    FROM @foo AS f, Numbers AS n
    WHERE n.Number <= f.[count];
    

    결과 (다시, SQL 서버) :

    value | count | index
    ------+-------+------
    foo   |     1 |     1
    bar   |     3 |     1
    bar   |     3 |     2
    bar   |     3 |     3
    baz   |     2 |     1
    baz   |     2 |     2
    
  6. ==============================

    6.감사의 경우에만 SQL 서버 2005 이상 반복적으로이 문제를 처리 할 수 ​​있습니다 :

    감사의 경우에만 SQL 서버 2005 이상 반복적으로이 문제를 처리 할 수 ​​있습니다 :

    declare @Stuff as Table ( Name VarChar(10), Number Int )
    insert into @Stuff ( Name, Number ) values ( 'foo', 1 ), ( 'bar', 3 ), ( 'baz', 2 )
    
    select * from @Stuff
    
    ; with Repeat ( Name, Number, Counter ) as (
      select Name, Number, 1
        from @Stuff
        where Number > 0
      union all
      select Name, Number, Counter + 1
        from Repeat
        where Counter < Number
      )
    select *
      from Repeat
      order by Name, Counter -- Group by name.
      option ( maxrecursion 0 )
    
  7. ==============================

    7.간단한함으로써 레코드 n 번 반복 목표에 도달 할 수 있습니다 가입. 다음 쿼리는 각 레코드를 20 회 반복합니다.

    간단한함으로써 레코드 n 번 반복 목표에 도달 할 수 있습니다 가입. 다음 쿼리는 각 레코드를 20 회 반복합니다.

    SELECT  TableName.*
    FROM    TableName
    JOIN    master.dbo.spt_values on type = 'P' and number < 20
    

    형 = 'P'에 master.dbo.spt_values에 대한 참고 : 이 테이블 형태의 상태 = 'P'가 그 안에 하드 코드 번호의 시리즈를 얻기 위해 사용된다.

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

    8.당신은 CTE로 사용할 수 있습니다 :

    당신은 CTE로 사용할 수 있습니다 :

    WITH Numbers(Num) AS
    (
        SELECT 1 AS Num
        UNION ALL 
        SELECT Num + 1
        FROM   Numbers c
        WHERE  c.Num < 1000
    )
    
    SELECT VALUE,COUNT, number
    FROM   TABLE
           JOIN Numbers
                ON  TABLE.count >= Numbers.Num
    OPTION(MAXRECURSION 1000)
    
  9. ==============================

    9.오라클, 우리는 LEVEL 및 CROSS 조인의 조합을 사용할 수 있습니다.

    오라클, 우리는 LEVEL 및 CROSS 조인의 조합을 사용할 수 있습니다.

      SELECT *
        FROM yourtable
             CROSS JOIN (    SELECT ROWNUM index_t
                               FROM DUAL
                         CONNECT BY LEVEL <= (SELECT MAX (count_t) FROM yourtable))
       WHERE index_t <= count_t
    ORDER BY VALUE, index_t;
    

    데모

  10. from https://stackoverflow.com/questions/10423767/sql-repeat-a-result-row-multiple-times-and-number-the-rows by cc-by-sa and MIT license