복붙노트

[SQL] PostgreSQL의 크로스 탭 쿼리

SQL

PostgreSQL의 크로스 탭 쿼리

하나는 PostgreSQL의에서 크로스 탭 쿼리를 만드는 방법을 알고 있나요? 예를 들어, 나는 다음과 같은 테이블이 있습니다 :

Section    Status    Count
A          Active    1
A          Inactive  2
B          Active    4
B          Inactive  5

나는 다음과 같은 크로스 탭을 반환하는 쿼리를 싶습니다

Section    Active    Inactive
A          1         2
B          4         5

이게 가능해?

해결법

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

    1.함수 교차 제공 데이터베이스 당 한번 추가 모듈 tablefunc를 설치 (). 포스트 그레스 9.1 이후 해당에 대한 정보를 만들 수 있습니다 :

    함수 교차 제공 데이터베이스 당 한번 추가 모듈 tablefunc를 설치 (). 포스트 그레스 9.1 이후 해당에 대한 정보를 만들 수 있습니다 :

    CREATE EXTENSION IF NOT EXISTS tablefunc;
    
    CREATE TABLE tbl (
       section   text
     , status    text
     , ct        integer  -- "count" is a reserved word in standard SQL
    );
    
    INSERT INTO tbl VALUES 
      ('A', 'Active', 1), ('A', 'Inactive', 2)
    , ('B', 'Active', 4), ('B', 'Inactive', 5)
                        , ('C', 'Inactive', 7);  -- ('C', 'Active') is missing
    

    교차 1 개 입력 파라미터 (텍스트) :

    SELECT *
    FROM   crosstab(
       'SELECT section, status, ct
        FROM   tbl
        ORDER  BY 1,2'  -- needs to be "ORDER BY 1,2" here
       ) AS ct ("Section" text, "Active" int, "Inactive" int);
    

    보고:

     Section | Active | Inactive
    ---------+--------+----------
     A       |      1 |        2
     B       |      4 |        5
     C       |      7 |           -- !!
    

    교차 2 개 입력 파라미터들 (텍스트, 텍스트)

    SELECT *
    FROM   crosstab(
       'SELECT section, status, ct
        FROM   tbl
        ORDER  BY 1,2'  -- could also just be "ORDER BY 1" here
    
      , $$VALUES ('Active'::text), ('Inactive')$$
       ) AS ct ("Section" text, "Active" int, "Inactive" int);

    보고:

     Section | Active | Inactive
    ---------+--------+----------
     A       |      1 |        2
     B       |      4 |        5
     C       |        |        7  -- !!
    

    DB <> 바이올린 여기

    포스트 그레스 9.6 기본 대화 형 터미널 psql의이 메타 명령을 추가했다. 당신은 당신이 첫번째 크로스 탭 () 매개 변수로 사용하고 \ crosstabview (즉시 또는 다음 단계에서)에 공급 것 쿼리를 실행할 수 있습니다. 처럼:

    db=> SELECT section, status, ct FROM tbl \crosstabview
    

    비슷한 결과는 위와 같이하지만, 전용 클라이언트 측에서 표현 기능입니다. 입력 행은 따라서 ORDER BY가 필요하지, 약간 다르게 처리됩니다. 설명서의 \ crosstabview에 대한 세부 사항. 해당 페이지의 하단에 더 많은 코드 예제가 있습니다.

    다니엘 베리 테 (psql의 기능의 저자)에 의해 dba.SE에 대답 관련 :

    이전에 허용 대답은 구식이다.

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

    2.당신이 데이터베이스에 한 번 설치해야합니다 - 당신은 추가 모듈 tablefunc의 크로스 탭 () 함수를 사용할 수 있습니다. PostgreSQL의 9.1 이후 해당에 대한 정보를 만들 수 있습니다 :

    당신이 데이터베이스에 한 번 설치해야합니다 - 당신은 추가 모듈 tablefunc의 크로스 탭 () 함수를 사용할 수 있습니다. PostgreSQL의 9.1 이후 해당에 대한 정보를 만들 수 있습니다 :

    CREATE EXTENSION tablefunc;
    

    귀하의 경우에는, 나는 다음과 같이 보일 것입니다 생각 :

    CREATE TABLE t (Section CHAR(1), Status VARCHAR(10), Count integer);
    
    INSERT INTO t VALUES ('A', 'Active',   1);
    INSERT INTO t VALUES ('A', 'Inactive', 2);
    INSERT INTO t VALUES ('B', 'Active',   4);
    INSERT INTO t VALUES ('B', 'Inactive', 5);
    
    SELECT row_name AS Section,
           category_1::integer AS Active,
           category_2::integer AS Inactive
    FROM crosstab('select section::text, status, count::text from t',2)
                AS ct (row_name text, category_1 text, category_2 text);
    
  3. ==============================

    3.

    SELECT section,
           SUM(CASE status WHEN 'Active' THEN count ELSE 0 END) AS active, --here you pivot each status value as a separate column explicitly
           SUM(CASE status WHEN 'Inactive' THEN count ELSE 0 END) AS inactive --here you pivot each status  value as a separate column explicitly
    
    FROM t
    GROUP BY section
    
  4. ==============================

    4.JSON 집계과 해결 방법 :

    JSON 집계과 해결 방법 :

    CREATE TEMP TABLE t (
      section   text
    , status    text
    , ct        integer  -- don't use "count" as column name.
    );
    
    INSERT INTO t VALUES 
      ('A', 'Active', 1), ('A', 'Inactive', 2)
    , ('B', 'Active', 4), ('B', 'Inactive', 5)
                       , ('C', 'Inactive', 7); 
    
    
    SELECT section,
           (obj ->> 'Active')::int AS active,
           (obj ->> 'Inactive')::int AS inactive
    FROM (SELECT section, json_object_agg(status,ct) AS obj
          FROM t
          GROUP BY section
         )X
    
  5. ==============================

    5.내가 여기를 테스트 할 수 있지만, 올바른 방향으로 당신을 얻을 수 있기 때문에 죄송이 완료되지 않았습니다. 나는 비슷한 쿼리를 만드는 뭔가 I의 사용으로 번역하고 있습니다 :

    내가 여기를 테스트 할 수 있지만, 올바른 방향으로 당신을 얻을 수 있기 때문에 죄송이 완료되지 않았습니다. 나는 비슷한 쿼리를 만드는 뭔가 I의 사용으로 번역하고 있습니다 :

    select mt.section, mt1.count as Active, mt2.count as Inactive
    from mytable mt
    left join (select section, count from mytable where status='Active')mt1
    on mt.section = mt1.section
    left join (select section, count from mytable where status='Inactive')mt2
    on mt.section = mt2.section
    group by mt.section,
             mt1.count,
             mt2.count
    order by mt.section asc;
    

    내가에서 일하고 있어요 코드는 다음과 같습니다

    select m.typeID, m1.highBid, m2.lowAsk, m1.highBid - m2.lowAsk as diff, 100*(m1.highBid - m2.lowAsk)/m2.lowAsk as diffPercent
    from mktTrades m
       left join (select typeID,MAX(price) as highBid from mktTrades where bid=1 group by typeID)m1
       on m.typeID = m1.typeID
       left join (select typeID,MIN(price) as lowAsk  from mktTrades where bid=0 group by typeID)m2
       on m1.typeID = m2.typeID
    group by m.typeID, 
             m1.highBid, 
             m2.lowAsk
    order by diffPercent desc;
    

    유형 ID, 최고 가격 입찰 및 최저 가격을 물어 둘 사이의 차이를 반환하는 (무언가를 의미 할 것입니다 긍정적 인 변화를이 판매 될 수있는 것보다 적은 비용으로 구입하실 수 있습니다).

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

    6.크로스 탭 기능은 tablefunc 확장에 따라 사용할 수 있습니다. 당신은 데이터베이스에 대해이 확장 한 시간을 만들어야합니다.

    크로스 탭 기능은 tablefunc 확장에 따라 사용할 수 있습니다. 당신은 데이터베이스에 대해이 확장 한 시간을 만들어야합니다.

    EXTENSION의 tablefunc을 만들;

    당신은 크로스 탭을 사용하여 피벗 테이블을 만들려면 다음 코드를 사용할 수 있습니다 :

    create table test_Crosstab( section text,
    <br/>status text,
    <br/>count numeric)
    
    <br/>insert into test_Crosstab values ( 'A','Active',1)
                    <br/>,( 'A','Inactive',2)
                    <br/>,( 'B','Active',4)
                    <br/>,( 'B','Inactive',5)
    
    select * from crosstab(
    <br/>'select section
        <br/>,status
        <br/>,count
        <br/>from test_crosstab'
        <br/>)as ctab ("Section" text,"Active" numeric,"Inactive" numeric)
    
  7. from https://stackoverflow.com/questions/3002499/postgresql-crosstab-query by cc-by-sa and MIT license