PostgreSQL에서 피벗 테이블 생성
피벗 테이블은 대규모 데이터 흐름을 요약하는 데 사용되는 원래 테이블에 이미 제공된 일부 값을 집계하는 경향이 있습니다. PostgreSQL에서는 결과에 요약된 행의 데이터 유형인 사용자 지정 N
값 열과 함께 반환된 테이블입니다.
오늘 우리는 기존 값이 있는 미리 정의된 테이블을 사용하여 PostgreSQL에서 피벗 테이블을 만드는 방법을 배울 것입니다.
crosstab()
을 사용하여 PostgreSQL에서 피벗 테이블 생성
PostgreSQL 설명서의 TABLE_FUNC
제목 아래 crosstab()
을 찾을 수 있습니다. 여러 행이 있는 테이블을 반환하는 함수입니다.
통사론:
crosstab ( sql text ) ? setof record
이 쿼리는 행 이름과 N
값 열을 포함하는 피벗 테이블을 생성합니다. 여기서 N
은 호출 쿼리에 지정된 행 유형에 의해 결정됩니다.
crosstabN ( sql text ) , setof table_crosstab_N
이 쿼리는 행 이름과 N
값 열을 포함하는 피벗 테이블을 생성합니다. crosstab2
, crosstab3
및 crosstab4
가 미리 정의되어 있습니다.
이제 어떻게 사용할 수 있는지 봅시다. 열이 있는 APARTMENT
라는 간단한 테이블을 생성합니다. ID
, UNIT
, PRICE
, AREA
.
예:
CREATE TABLE apartment (
ID int PRIMARY KEY,
UNIT int,
PRICE int,
AREA int
)
이제 테이블에 몇 가지 값을 추가해 보겠습니다.
INSERT INTO apartment VALUES (1, 20, 200, 10) , (2, 20, 200, 9), (3, 50, 190, 8);
그래서 지금 우리 테이블을 보면 다음과 같을 것입니다.
출력:
id unit price area
1 20 200 10
2 20 200 9
3 50 190 8
피벗 테이블에서 이 테이블은 다음과 같이 표시됩니다.
unit ..180 190 200 210...
20 - - 19/2 = 9.5 -
50 - 8 - -
따라서 여기서는 특정 PRICES
에서 각 UNIT
에 대한 AREA
의 평균을 취합니다. 우리는 언급된 PRICE
에서 얻을 수 있는 평균 AREA
를 보고 싶습니다.
따라서 20
의 UNIT
에 대해 200
의 PRICE
에 대한 평균 AREA
를 찾으면 (10 + 9) / 2 = 8
로 평균을 얻게 됩니다. 이러한 방식으로 집계가 있는 피벗 테이블을 찾습니다.
이제 개념을 이해했으므로 계속해서 구현해 보겠습니다. 다음과 같이 쿼리를 작성할 수 있습니다.
Select UNIT, PRICE, avg(area)
from apartment
group by UNIT, PRICE
이 쿼리는 우리가 원하는 기본 기능을 구현합니다. GROUP BY
절을 사용하여 집계하려는 테이블의 열을 가져옵니다.
특정 UNIT
및 PRICE
에 대한 AREA
의 평균을 찾고자 합니다. 따라서 이 두 열을 사용하여 그룹화합니다. 다음과 같이 테이블이 반환됩니다.
출력:
unit price avg
50 190 8.0000000000000000
20 200 9.5000000000000000
이제 이 테이블도 제대로 작동하지만 계속해서 crosstab()
을 사용하겠습니다. 작동 방식과 제약 조건을 살펴봐야 합니다.
crosstab()
을 사용하려면 두 가지 중요한 사항을 확인해야 합니다.
crosstab()
에는 각 행에 대해 고유한 값이 있어야 합니다.crosstab()
은 각 열에 대해 동일한 데이터 유형을 가져야 합니다.
따라서 데이터 유형이 다른 열이 없는지 확인하십시오. 이제 이 GROUP BY
쿼리의 결과를 피벗하기 위해 다음과 같이 작성해 보겠습니다.
select *
from crosstab
(
'Select UNIT::float, PRICE::float, avg(AREA)::float
from apartment
group by UNIT, PRICE') as ct(
UNIT float,
avge float
);
여기서 고려해야 할 몇 가지 중요한 사항이 있습니다. UNIT
및 avge
라는 두 개의 열로 정의된 결과 테이블 CT
로 반환된 crosstab
에서 열을 선택합니다.
그룹화 후 APARTMENT
에서 열을 가져오고 평균을 찾습니다. 이 쿼리 테이블은 최종 결과를 위해 피벗됩니다.
또한 각 열을 동일한 데이터 유형으로 변환해야 합니다. 물론 평균은 배정밀도이거나 실수입니다.
따라서 불필요하더라도 int 열을 float로 캐스트하는 것이 좋습니다. 캐스팅하지 않고 쿼리를 실행하면 아래와 같은 오류가 반환됩니다.
출력:
ERROR: return and sql tuple descriptions are incompatible
SQL state: 42601
따라서 이를 방지하기 위해 float로 캐스팅하거나 float 유형으로 값이 삽입된 새 테이블을 생성해야 합니다. 데이터 유형의 차이는 튜플을 호환되지 않게 만드는 것입니다.
출력:
unit avg
50 8
20 9.5
다른 경우에는 crosstab()
을 사용할 필요가 없습니다. GROUP BY
를 사용해도 평균을 얻기 위한 고유한 값이 있는 테이블을 반환하므로 효과적입니다.
crosstab()
함수를 사용하지 않았다면 여전히 다음과 같은 결과를 얻었을 것입니다.
unit price avg
50 190 8
20 200 9.5
crosstab()
에서 세 개의 열이 있는 반환 목록을 사용하여 여전히 UNIT
와 area
의 평균을 포함하는 값만 반환한다는 것을 알 수 있습니다. 왜?
SQL 문은 일련의 범주와 값을 사용하며 이 경우 범주는 UNIT
가 되고 값은 평균 열이 되는 경향이 있습니다. 따라서 반환 테이블에는 두 개의 열만 유지됩니다.
crosstab()
이 필요에 따라 작동하는 방식을 알았으므로 이제 사용할 수 있습니다. 다른 PRICES
가 있는 UNITS
가 있는 경우 AVG()
를 가져오면 데이터에 따라 N
개의 열이 있게 됩니다.
테이블의 값을 다음과 같이 변경해 보겠습니다.
id unit price area
1 20 200 10
2 20 170 9
3 50 190 8
이제 여기에서 crosstab()
쿼리를 실행하면 다음과 같은 결과가 반환됩니다.
출력:
unit avge avge1
50 8 [NULL]
20 10 9
PRICE
를 변경하면 AREA
값이 다른 평균으로 분산되는 경향이 있음을 알 수 있습니다. 이는 평균을 가격별로 그룹화하기 때문에 발생합니다.
동일한 PRICE
값은 모든 값에 대해 존재하는 경우 서로 다른 값의 평균을 가지지만 다른 PRICE
값은 각 PRICE
에 해당하는 AREAS
의 평균으로만 구성됩니다. 따라서 표는 이런 식으로 정렬됩니다.
Hello, I am Bilal, a research enthusiast who tends to break and make code from scratch. I dwell deep into the latest issues faced by the developer community and provide answers and different solutions. Apart from that, I am just another normal developer with a laptop, a mug of coffee, some biscuits and a thick spectacle!
GitHub