이 문제를 해결하기 위해 취해야 할 단계에 대해 좀 더 길고 자세한 설명을 추가하겠습니다. 너무 길면 사과드립니다.
나는 당신이 제공 한 기초부터 시작하여이 포스트의 나머지 부분에 사용할 몇 가지 용어를 정의하는 데 사용할 것입니다. 이것은 기본 테이블입니다 .
select * from history;
+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
| 1 | A | 10 |
| 1 | B | 3 |
| 2 | A | 9 |
| 2 | C | 40 |
+--------+----------+-----------+
이것이 우리의 목표, 예쁜 피벗 테이블입니다 .
select * from history_itemvalue_pivot;
+--------+------+------+------+
| hostid | A | B | C |
+--------+------+------+------+
| 1 | 10 | 3 | 0 |
| 2 | 9 | 0 | 40 |
+--------+------+------+------+
의 값 history.hostid
열이 될 것이다 y 값 피벗 테이블이다. 의 값 history.itemname
열이 될 것입니다 x 값 (분명한 이유를).
피벗 테이블을 만드는 문제를 해결해야하는 경우 3 단계 프로세스 (선택적 4 단계)를 사용하여 문제를 해결합니다.
- 관심있는 열을 선택하십시오 (예 : y- 값 및 x- 값)
- 추가 열을 사용하여 기본 테이블을 확장-각 x 값 마다 하나씩
- 확장 테이블 그룹화 및 집계-각 y- 값 에 대해 하나의 그룹
- (선택 사항) 집계 된 테이블을 확인
이 단계를 문제에 적용하고 우리가 얻는 것을 보자.
1 단계 : 관심의 선택 열 . 원하는 결과 hostid
에서 y 값 을 itemname
제공하고 x 값 을 제공 합니다 .
2 단계 : 여분의 열이 기본 테이블을 확장 . 일반적으로 x- 값당 하나의 열이 필요합니다. x- 값 열은 itemname
다음과 같습니다.
create view history_extended as (
select
history.*,
case when itemname = "A" then itemvalue end as A,
case when itemname = "B" then itemvalue end as B,
case when itemname = "C" then itemvalue end as C
from history
);
select * from history_extended;
+--------+----------+-----------+------+------+------+
| hostid | itemname | itemvalue | A | B | C |
+--------+----------+-----------+------+------+------+
| 1 | A | 10 | 10 | NULL | NULL |
| 1 | B | 3 | NULL | 3 | NULL |
| 2 | A | 9 | 9 | NULL | NULL |
| 2 | C | 40 | NULL | NULL | 40 |
+--------+----------+-----------+------+------+------+
우리는 행 수를 변경하지 않았으며 추가 열을 추가했습니다. 또한 NULL
s 의 패턴 - itemname = "A"
새 열에 대해서는 널이 아닌 값을 가지며 A
다른 새 열에 대해서는 널값을 갖는 행에 유의하십시오 .
3 단계 : 확장 테이블을 그룹화하고 집계합니다 . group by hostid
y- 값을 제공하기 때문에을 수행 해야 합니다.
create view history_itemvalue_pivot as (
select
hostid,
sum(A) as A,
sum(B) as B,
sum(C) as C
from history_extended
group by hostid
);
select * from history_itemvalue_pivot;
+--------+------+------+------+
| hostid | A | B | C |
+--------+------+------+------+
| 1 | 10 | 3 | NULL |
| 2 | 9 | NULL | 40 |
+--------+------+------+------+
(y- 값당 하나의 행 이 생겼습니다 .) 이제 거의 다 왔습니다 ! 우리는 그 추악한 것들을 제거해야합니다 NULL
.
4 단계 : prettify . 우리는 null 값을 0으로 대체하여 결과 집합을 더 잘 볼 수 있습니다.
create view history_itemvalue_pivot_pretty as (
select
hostid,
coalesce(A, 0) as A,
coalesce(B, 0) as B,
coalesce(C, 0) as C
from history_itemvalue_pivot
);
select * from history_itemvalue_pivot_pretty;
+--------+------+------+------+
| hostid | A | B | C |
+--------+------+------+------+
| 1 | 10 | 3 | 0 |
| 2 | 9 | 0 | 40 |
+--------+------+------+------+
그리고 우리는 끝났습니다-우리는 MySQL을 사용하여 멋진 피벗 테이블을 만들었습니다.
이 절차를 적용 할 때 고려해야 할 사항 :
- 추가 열에 사용할 값
itemvalue
이 예제에서 사용 했습니다
- 추가 열에 사용할 "중립"값 나는 사용
NULL
했지만 정확한 상황에 따라 0
또는 ""
일 수도 있습니다.
- 그룹화 할 때 사용할 집계 함수 내가 사용
sum
하지만, count
그리고 max
종종 사용된다 (max
여러 행에 걸쳐 확산 있었다 하나의 행 "객체"를 구축 할 때 자주 사용된다)
- y- 값에 여러 열을 사용합니다. 이 솔루션은 y 값에 단일 열을 사용하는 것으로 제한되지 않습니다-여분의 열을
group by
절에 연결하십시오 (그리고 잊지 마십시오 select
).
알려진 제한 사항 :
- 이 솔루션은 피벗 테이블에서 n 개의 열을 허용하지 않습니다. 기본 테이블을 확장 할 때 각 피벗 열을 수동으로 추가해야합니다. 따라서 5 또는 10 x 값의 경우이 솔루션이 좋습니다. 100에 대해서는 그렇게 좋지 않습니다. 쿼리를 생성하는 저장 프로 시저가있는 몇 가지 솔루션이 있지만 추악하고 제대로 이해하기가 어렵습니다. 현재 피벗 테이블에 많은 열이 필요할 때이 문제를 해결하는 좋은 방법을 모릅니다.