복붙노트

[SQL] 하나의 SQL 문을 사용하여 여러 최대 () 값을 선택

SQL

하나의 SQL 문을 사용하여 여러 최대 () 값을 선택

나는 데이터가있는 테이블이 그 같은 외모 뭔가 :

data_type, value
World of Warcraft, 500
Quake 3, 1500
Quake 3, 1400
World of Warcraft, 1200
Final Fantasy, 100
Final Fantasy, 500

내가하고 싶은 하나의 문에 각 값의 최대 값을 선택합니다. 나는 쉽게 뭔가를 할 수있어

select data_type, max(value)
from table
where data_type = [insert each data type here for separate queries]
group by data_type

그러나 디스플레이가에 내가 원하는 것은

select data_type, 
  max(value) as 'World of Warcraft', 
  max(value) as 'Quake 3', 
  max(value) as 'Final Fantasy'

나는 하나의 성명에서 이들 각각의 최대 값을 얻을 수 있도록. 나는이 일에 대해 어떻게 갈 것인가?

해결법

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

    1.별도의 열에 각 DATA_TYPE의 최대 값을 반환 할 경우, 당신은 CASE 표현식으로 집계 함수를 사용할 수 있어야합니다 :

    별도의 열에 각 DATA_TYPE의 최대 값을 반환 할 경우, 당신은 CASE 표현식으로 집계 함수를 사용할 수 있어야합니다 :

    select
      max(case when data_type='World of Warcraft' then value end) WorldofWarcraft,
      max(case when data_type='Quake 3' then value end) Quake3,
      max(case when data_type='Final Fantasy' then value end) FinalFantasy
    from yourtable;
    

    데모와 SQL 바이올린을 참조하십시오

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

    2.다시 한번, 몇 가지의 "데이터 유형"이상, 나는 () 사용 크로스 탭에 제안한다 :

    다시 한번, 몇 가지의 "데이터 유형"이상, 나는 () 사용 크로스 탭에 제안한다 :

    SELECT * FROM crosstab(
         $$SELECT DISTINCT ON (1, 2)
                  'max' AS "type", data_type, val
           FROM   tbl
           ORDER  BY 1, 2, val DESC$$
    
        ,$$VALUES ('Final Fantasy'), ('Quake 3'), ('World of Warcraft')$$)
    AS x ("type" text, "Final Fantasy" int, "Quake 3" int, "World of Warcraft" int)
    

    보고:

    type | Final Fantasy | Quake 3 | World of Warcraft
    -----+---------------+---------+-------------------
    max  | 500           | 1500    |    1200
    

    기본 사항에 대한 자세한 설명 : PostgreSQL의 크로스 탭 쿼리

    그것을 위해 작동하도록 : 까다로운 것은이 완전히 동적으로 만들 것입니다

    적어도 유형은 잘 알려져있다 : 정수를이 경우.

    (9.3 포함) 현재의 PostgreSQL 불가능하다는 : 짧은합니다. 다형성 종류와 배열이나 hstore 유형에 제한을 우회 할 수있는 방법으로 근사치가 있습니다. 당신을 위해 충분히 좋은 수 있음. 그러나 그것은 하나의 SQL 쿼리의 개별 열 결과를 얻기 위해 엄격 수 없습니다. SQL은 형식에 대한 매우 견고하고 다시 무엇을 기대해야하는지 알고 싶어.

    그러나, 두 개의 쿼리 수행 할 수 있습니다. 첫 번째는 사용의 실제 쿼리를 작성합니다. 위의 간단한 경우에 건물 :

    SELECT $f$SELECT * FROM crosstab(
         $$SELECT DISTINCT ON (1, 2)
                  'max' AS "type", data_type, val
           FROM   tbl
           ORDER  BY 1, 2, val DESC$$
    
        ,$$VALUES ($f$     || string_agg(quote_literal(data_type), '), (') || $f$)$$)
    AS x ("type" text, $f$ || string_agg(quote_ident(data_type), ' int, ') || ' int)'
    FROM  (SELECT DISTINCT data_type FROM tbl) x
    

    이것은 당신이 실제로 필요로하는 쿼리를 생성합니다. 동시성 문제를 방지하기 위해 동일한 트랜잭션 내에서 두 번째를 실행합니다.

    이름 방지 SQL 주입 (컬럼) 불법의 모든 종류의 살균 할을 quote_literal ()와에서 quote_ident ()의 전략적 사용을합니다.

    수행 달러 인용 부호의 여러 계층에 의해 혼동되지. 즉 동적 쿼리를 구축 할 필요가있다. 나는 가능한 한 간단하게 넣어.

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

    3.당신이 당신의 데이터를 하나의 문자열로 집계 할 경우 각 유형에 대한 기록을 가진 레코드를 필요로하는 경우, bluefeet 예로 이동 :

    당신이 당신의 데이터를 하나의 문자열로 집계 할 경우 각 유형에 대한 기록을 가진 레코드를 필요로하는 경우, bluefeet 예로 이동 :

    select
        data_type,
        max(value) as value
    from table1
    group by data_type
    
  4. from https://stackoverflow.com/questions/18494829/selecting-multiple-max-values-using-a-single-sql-statement by cc-by-sa and MIT license