복붙노트

[SQL] 그룹 당 첫 번째와 마지막 행에서 값을 가져 오기

SQL

그룹 당 첫 번째와 마지막 행에서 값을 가져 오기

내가 MySQL의에서 오는 너희들 중 하나가 나를 도울 수있을 것이라고 기대하고, 포스트 그레스에 새로운 해요.

이름, 주 및 가치 : 나는 3 열이있는 테이블이 있습니다. 이 표는 이름의 기록, 그들이 높이를 기록하는 주, 그들의 높이의 값을가집니다. 이 같은:

Name  |  Week  | Value
------+--------+-------
John  |  1     | 9
Cassie|  2     | 5
Luke  |  6     | 3
John  |  8     | 14
Cassie|  5     | 7
Luke  |  9     | 5
John  |  2     | 10
Cassie|  4     | 4
Luke  |  7     | 4

내가 원하는 최소 일주일에 한 값과 최대 주 사용자 당 목록입니다. 이 같은:

Name  |minWeek | Value |maxWeek | value
------+--------+-------+--------+-------
John  |  1     | 9     | 8      | 14
Cassie|  2     | 5     | 5      | 7
Luke  |  6     | 3     | 9      | 5

포스트 그레스에서,이 쿼리를 사용 :

select name, week, value
from table t
inner join(
select name, min(week) as minweek
from table
group by name)
ss on t.name = ss.name and t.week = ss.minweek
group by t.name
;

그러나, 나는 오류가 발생 :

내가 여기 잘못 뭘하는지 궁금하네요 그래서 이것은 MySQL의에서 나를 위해 벌금을했다?

해결법

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

    1.포스트 그레스)는 FIRST_VALUE 좋은 창 기능을 가지고있다 ()와 (LAST_VALUE 때문에, 고통을 조금이지만, 이러한 통합 기능하지 않습니다. 그래서, 여기에 한 가지 방법은 다음과 같습니다

    포스트 그레스)는 FIRST_VALUE 좋은 창 기능을 가지고있다 ()와 (LAST_VALUE 때문에, 고통을 조금이지만, 이러한 통합 기능하지 않습니다. 그래서, 여기에 한 가지 방법은 다음과 같습니다

    select t.name, min(t.week) as minWeek, max(firstvalue) as firstvalue,
           max(t.week) as maxWeek, max(lastvalue) as lastValue
    from (select t.*, first_value(value) over (partition by name order by week) as firstvalue,
                 last_value(value) over (partition by name order by week) as lastvalue
          from table t
         ) t
    group by t.name;
    
  2. ==============================

    2.다양한 간단하고 빠른 방법이 있습니다.

    다양한 간단하고 빠른 방법이 있습니다.

    SELECT *
    FROM  (
       SELECT DISTINCT ON (name)
              name, week AS first_week, value AS first_val
       FROM   tbl
       ORDER  BY name, week
       ) f
    JOIN (
       SELECT DISTINCT ON (name)
              name, week AS last_week, value AS last_val
       FROM   tbl
       ORDER  BY name, week DESC
       ) l USING (name);
    

    이하 :

    SELECT *
    FROM  (SELECT DISTINCT ON (1) name, week AS first_week, value AS first_val
           FROM   tbl ORDER BY 1,2) f
    JOIN  (SELECT DISTINCT ON (1) name, week AS last_week, value AS last_val
           FROM   tbl ORDER BY 1,2 DESC) l USING (name);
    

    간단하고 이해하기 쉽다. 또한 빠른 내 시험한다. DISTINCT ON에 대한 상세 설명 :

    집계 기능 분 () 또는 최대 ()를 입력으로 복합 형을 받아들이지 않는다. 당신은 (즉, 열심히하지 않은) 사용자 정의 집계 함수를 작성해야합니다. 그러나 윈도우 함수의 FIRST_VALUE () 및 LAST_VALUE ()는 않습니다. 우리는 아주 간단한 해결책을 고안 할 수 있음에 건물 :

    SELECT DISTINCT ON (name)
           name, week AS first_week, value AS first_value
         ,(first_value((week, value)) OVER (PARTITION BY name
                                            ORDER BY week DESC))::text AS l
    FROM   tbl t
    ORDER  BY name, week;
    

    출력은 모든 데이터를 가지고 있지만, 지난 주에 대한 값은 익명의 기록에 박제되어있다. 당신은 분해 된 값을해야 할 수도 있습니다.

    우리가 시스템에 포함 된 요소의 유형을 등록하는 잘 알려진 유형을 필요로하십시오. 적응 테이블 정의 직접 테이블 형식 자체의 기회 사용이 가능합니다 :

    CREATE TABLE tbl (week int, value int, name text) -- note optimized column order
    

    주말 값이 먼저 온다.

    SELECT (l).name, first_week, first_val
         , (l).week AS last_week, (l).value AS last_val
    FROM (
       SELECT DISTINCT ON (name)
              week AS first_week, value AS first_val
             ,first_value(t) OVER (PARTITION BY name ORDER BY week DESC) AS l
       FROM   tbl t
       ORDER  BY name, week
       ) sub;
    

    그러나, 대부분의 경우에 아마 수 없습니다. 그냥 (임시 사용) 임시 테이블을 CREATE TYPE (영구) 만들기에서 사용자 정의 유형을 사용하거나에서 :

    CREATE TEMP TABLE nv(last_week int, last_val int);  -- register composite type
    
    SELECT name, first_week, first_val, (l).last_week, (l).last_val
    FROM (
       SELECT DISTINCT ON (name)
              name, week AS first_week, value AS first_val
             ,first_value((week, value)::nv) OVER (PARTITION BY name
                                                   ORDER BY week DESC) AS l
       FROM   tbl t
       ORDER  BY name, week
       ) sub;
    

    50,000 행의 유사한 테이블 포스트 그레스 9.3의 로컬 테스트에서, 이러한 쿼리의 각 빠르게 현재 허용 대답보다 훨씬이었다. 와 시험 분석 설명한다.

    모든 표시 SQL 바이올린.

  3. from https://stackoverflow.com/questions/25170215/get-values-from-first-and-last-row-per-group by cc-by-sa and MIT license