oracle - 动态将行转换为列
问题描述
我有这张表,条件是一个产品最多可以有 4 个标签(4 个标签名称/LN,4 个标签位置/LP):
PRODUCT_CODE LABEL_NAME PLACEMENT_DETAIL
---------------------------------------------
307960-010 Trademark Bottom Left
307960-010 228119 Middle Left
307960-010 YCM Sticker Bottom Right
307960-015 Trademark Bottom Left
307960-016 Trademark Bottom Left
307960-017 Trademark Bottom Left
307960-020 228119 Middle Left
307960-020 Trademark Bottom Left
我想显示如下表格:
产品代码 LN1 LP1 LN2 LP2 LN3 LP3 LN4 LP4
307960-010 商标左下 228119 左中 YCM 贴纸右下 307960-015 商标左下角 307960-016 商标左下角 307960-017 商标左下角 307960-020 228119 左中商标左下
我尝试使用带有定义的标签名称或位置的 DECODE,但它与我想要的相差甚远,因为有超过 20 种标签,它的外观如下:
SELECT
PRODUCT_CODE,
DECODE(LABEL_NAME,'Trademark',label_name) AS "LN1",
DECODE(PLACEMENT_DETAIL,'Bottom Left',PLACEMENT_DETAIL) AS "LP1",
DECODE(LABEL_NAME,'228119',label_name) AS "LN2",
DECODE(PLACEMENT_DETAIL,'Middle Left',PLACEMENT_DETAIL) AS "LP2",
DECODE(LABEL_NAME,'YCM Sticker',label_name) AS "LN3",
DECODE(PLACEMENT_DETAIL,'Bottom Right',PLACEMENT_DETAIL) AS "LP3"
-- etc until all labels declared
FROM
(SELECT
PPL.*,
PML.LABEL_NAME
FROM
MES.PL_PRODCODE_LABEL PPL, MES.PL_MASTER_LABEL PML
WHERE
PPL.ID_LABEL = PML.ID_LABEL
AND PPL.STATUS_USE = 'Y'
AND PML.STATUS_USE = 'Y'
ORDER BY 2
)
结果如下:
PRODUCT_CODE LN1 LP1 LN2 LP2 LN3 LP3
307960-010 商标左下角 307960-010 228119 中左 307960-010 YCM 贴纸右下 307960-015 商标左下角 307960-016 商标左下角 307960-017 商标左下角 307960-020 228119 中左 307960-020 商标左下角
如何达到这样的效果?
谢谢你。
解决方案
你想PIVOT
row_number()
在执行此操作之前,为每个产品代码 ( )分配一个起始值partition by product_code
,根据您希望标签的优先级排序。
在该pivot
子句中,对于产品的每个可能的条目数,取标签和位置的min
(或):max
create table t (
product_code varchar2(10),
label_name varchar2(20),
placement varchar2(20)
);
insert into t values ( '307960-010', 'Trademark', 'Bottom Left' );
insert into t values ( '307960-010', '228119', 'Middle Left' );
insert into t values ( '307960-010', 'YCM Sticker', 'Bottom Right' );
insert into t values ( '307960-015', 'Trademark', 'Bottom Left' );
insert into t values ( '307960-016', 'Trademark', 'Bottom Left' );
insert into t values ( '307960-017', 'Trademark', 'Bottom Left' );
insert into t values ( '307960-020', '228119', 'Middle Left' );
insert into t values ( '307960-020', 'Trademark', 'Bottom Left' );
with rws as (
select t.*,
row_number () over (
partition by product_code
order by label_name, placement
) rn
from t
)
select * from rws
pivot (
min ( label_name ) ln, min ( placement ) lp
for rn in ( 1, 2, 3 )
);
PRODUCT_CODE 1_LN 1_LP 2_LN 2_LP 3_LN 3_LP
307960-010 228119 Middle Left Trademark Bottom Left YCM Sticker Bottom Right
307960-015 Trademark Bottom Left <null> <null> <null> <null>
307960-016 Trademark Bottom Left <null> <null> <null> <null>
307960-017 Trademark Bottom Left <null> <null> <null> <null>
307960-020 228119 Middle Left Trademark Bottom Left <null> <null>
推荐阅读
- java - 从 Libs 文件夹更改 Gradle 编译 .jar 路径
- python - 如何使用 jQuery Ajax 调用 Django 视图从数据库中检索数据
- c - 为什么具有位域的结构的大小大于应有的大小?
- heroku - Heroku:编辑已安装的 python 库的文件
- webpack - Webpack:使用外部注入需求
- symfony - Symfony 3 - 教义 2:聚合子句不起作用
- python - 正则表达式 - 提取年份
- angular - 更新用户配置文件不起作用
- bash - 执行sh脚本文件后如何防止docker容器停止
- php - 我需要在 PHP ldap_bind() 中转义用户密码吗?