Sql 透视表:如果其中一个参数为空,则连接同一条记录
我有这个国家标签表: Country_Code | Product_Code | Label_Name | Placement IT PR_I01 T-Label Top Left IT PR_I01 Instruction Bottom Center HK PR_H34 Tag Bottom Left HK HK Label Bottom Right US PR_U12 Sticker Bottom Center GB PR_G16 QR Code Bottom Right 如何达到这样的效果?Sql 透视表:如果其中一个参数为空,则连接同一条记录,sql,oracle,pivot,Sql,Oracle,Pivot,我有这个国家标签表: Country_Code | Product_Code | Label_Name | Placement IT PR_I01 T-Label Top Left IT PR_I01 Instruction Bottom Center HK PR_H34 Tag Bottom Left HK
谢谢。您可以通过使用
MAX()
对所有列进行聚合,但国家/地区代码
列除外,该列在从分区依据
列表中删除产品
后应位于主查询中的分组依据
中,例如
SELECT Country_Code,
MAX(product_code) AS Product_Code,
MAX("1_LN") AS Label_Name1,
MAX("1_LP") AS Placement1,
MAX("2_LN") AS Label_Name2,
MAX("2_LP") AS Placement2
FROM (WITH CNTRYRWS AS
(
SELECT Country_Code,
PRODUCT_CODE,
LABEL_NAME,
PLACEMENT,
ROW_NUMBER()
OVER(PARTITION BY Country_Code--, Product_Code
ORDER BY LABEL_NAME, PLACEMENT) RN
FROM PL_COUNTRY_LABEL_V
)
SELECT *
FROM CNTRYRWS
PIVOT
( MIN (LABEL_NAME) LN ,
MIN (PLACEMENT) LP FOR RN IN ( 1 AS "1" , 2 AS "2") ))
GROUP BY Country_Code
嗯。条件聚合似乎是一种简单的方法:
select country_code, max(product_code) as product_code,
max(case when seqnum = 1 then label_name end) as label_name_1,
max(case when seqnum = 1 then placement end) as placement_1,
max(case when seqnum = 2 then label_name end) as label_name_2,
max(case when seqnum = 2 then placement end) as placement_2
from (select c.*,
row_number() over (partition by country_code
order by product_code nulls last, label_name
) as seqnum
from PL_COUNTRY_LABEL_V c
) c
group by country_code
谢谢,但是如果我有多个产品代码与相同的国家代码,比如说我添加了新的香港标签与不同的产品代码,我不能使用国家代码和产品代码作为参数来调用它,因为我猜它最大。@Syns。这假定您知道结果集中的列数。如果不使用,则必须使用动态SQL。谢谢,我将了解一下动态SQL,因为它尚未使用。谢谢,如果有多个产品代码具有相同的国家/地区代码,该怎么办?它总是返回最大值。嗨@Syns。只要每个国家的产品代码最多是两个,就像你的情况一样(rn=1和2),那么就不会出现问题,正如你所看到的国家
HK
和IT
一样。嗨@Ozhan,这就是问题所在,我每个国家的产品代码会多得多,谢谢you@Syns让它充满活力不是问题,但你的案子越来越复杂了。最初,您需要删除空产品代码
值的额外行,现在每个国家/地区可以有多个产品代码
(假定为非空)。在这种情况下,您希望如何将非空产品代码与空产品代码放在一起??
SELECT CODE_COUNTRY,
PRODUCT_CODE,
"1_LN" Label_Name1,
"1_LP" Placement1,
"2_LN" Label_Name2,
"2_LP" Placement2
FROM (WITH CNTRYRWS
AS (SELECT CODE_COUNTRY,
PRODUCT_CODE,
LABEL_NAME,
PLACEMENT,
ROW_NUMBER ()
OVER (
PARTITION BY CODE_COUNTRY, product_code
ORDER BY LABEL_NAME, PLACEMENT
)
RN
FROM PL_COUNTRY_LABEL_V)
SELECT *
FROM CNTRYRWS PIVOT ( MIN (LABEL_NAME) LN , MIN (
PLACEMENT) LP FOR RN IN ( 1 AS "1" , 2
AS "2") ))
SELECT Country_Code,
MAX(product_code) AS Product_Code,
MAX("1_LN") AS Label_Name1,
MAX("1_LP") AS Placement1,
MAX("2_LN") AS Label_Name2,
MAX("2_LP") AS Placement2
FROM (WITH CNTRYRWS AS
(
SELECT Country_Code,
PRODUCT_CODE,
LABEL_NAME,
PLACEMENT,
ROW_NUMBER()
OVER(PARTITION BY Country_Code--, Product_Code
ORDER BY LABEL_NAME, PLACEMENT) RN
FROM PL_COUNTRY_LABEL_V
)
SELECT *
FROM CNTRYRWS
PIVOT
( MIN (LABEL_NAME) LN ,
MIN (PLACEMENT) LP FOR RN IN ( 1 AS "1" , 2 AS "2") ))
GROUP BY Country_Code
select country_code, max(product_code) as product_code,
max(case when seqnum = 1 then label_name end) as label_name_1,
max(case when seqnum = 1 then placement end) as placement_1,
max(case when seqnum = 2 then label_name end) as label_name_2,
max(case when seqnum = 2 then placement end) as placement_2
from (select c.*,
row_number() over (partition by country_code
order by product_code nulls last, label_name
) as seqnum
from PL_COUNTRY_LABEL_V c
) c
group by country_code