Tôi khuyên bạn nên áp dụng hàm UNPIVOT trước cho nhiều cột của bạn, sau đó sử dụng row_number()
để tạo tên cột mới của bạn sẽ được sử dụng trong PIVOT.
Cú pháp cơ bản cho việc bỏ chia sẻ sẽ là
select field,
value,
'value'||
to_char(row_number() over(partition by field
order by value)) seq
from yourtable
unpivot
(
value
for field in (Name, Age, Sex, DOB, col1, col2, col3)
) u;
Xem SQL Fiddle with Demo
. Điều này sẽ chuyển đổi nhiều cột dữ liệu của bạn thành nhiều hàng. Tôi đã sử dụng row_number()
để tạo một giá trị duy nhất cho tên cột mới của bạn, dữ liệu từ truy vấn này sẽ giống như sau:
| FIELD | VALUE | SEQ |
|-------|-------------------------|--------|
| AGE | 12 | value1 |
| AGE | 15 | value2 |
| COL1 | aa | value1 |
| COL1 | xx | value2 |
Sau đó, bạn có thể áp dụng hàm PIVOT cho kết quả này:
select field, value1, value2
from
(
select field,
value,
'value'||
to_char(row_number() over(partition by field
order by value)) seq
from yourtable
unpivot
(
value
for field in (Name, Age, Sex, DOB, col1, col2, col3)
) u
) d
pivot
(
max(value)
for seq in ('value1' as value1, 'value2' as value2)
) piv
Xem SQL Fiddle with Demo . Điều này cho kết quả cuối cùng:
| FIELD | VALUE1 | VALUE2 |
|-------|-------------------------|-------------------------|
| AGE | 12 | 15 |
| COL1 | aa | xx |
| COL2 | bb | yy |
| COL3 | cc | zz |
| DOB | 07-Aug-2001 12:00:00 AM | 26-Aug-2001 12:00:00 AM |
| NAME | A | B |
| SEX | F | M |
Lưu ý, khi bạn đang áp dụng chức năng hủy chia dữ liệu, kiểu dữ liệu của tất cả các cột phải giống nhau, do đó bạn có thể phải chuyển đổi dữ liệu của mình trong một truy vấn con trước khi có thể hủy chia dữ liệu đó.
Hàm UNPIVOT / PIVOT đã được giới thiệu trong Oracle 11g, nếu bạn đang sử dụng Oracle 10g, thì bạn có thể chỉnh sửa truy vấn để sử dụng:
with cte as
(
select 'name' field, name value
from yourtable
union all
select 'Age' field, Age value
from yourtable
union all
select 'Sex' field, Sex value
from yourtable
union all
select 'DOB' field, DOB value
from yourtable
union all
select 'col1' field, col1 value
from yourtable
union all
select 'col2' field, col2 value
from yourtable
union all
select 'col3' field, col3 value
from yourtable
)
select
field,
max(case when seq = 'value1' then value end) value1,
max(case when seq = 'value2' then value end) value2
from
(
select field, value,
'value'||
to_char(row_number() over(partition by field
order by value)) seq
from cte
) d
group by field;