db2 SQL -如何转置多个列?

mzmfm0qo  于 12个月前  发布在  DB2
关注(0)|答案(3)|浏览(175)

我在IBM DB2数据库中有一个表;我们称之为表1。看起来有点像这样:
| 客户|信息|提供A型销售|提供B类销售|提供C型销售|
| --|--|--|--|--|
| AA| X| 10 | 20 | 30 |
| BB| Y| 0 | 10 | 15 |
| CC| X| 20 | 0 | 30 |
我想做的是换位提供类型列创建一个单一的列标记提供类型和一个单一的列显示销售。有谁知道如何最好地做到这一点,请?
所需的输出应如下所示:
| 客户|信息|报价类型|销售|
| --|--|--|--|
| AA| X|一| 10 |
| AA| X| B| 20 |
| AA| X| C| 30 |
| BB| Y| B| 10 |
| BB| Y| C| 15 |
| CC| X|一| 20 |
| CC| X| C| 30 |

cnwbcb6i

cnwbcb6i1#

可能有一种方法可以使用unpivot,但这里有一个使用union的替代解决方案。

select customer, info, 'a' as offer_type, offer_type_a_sales as sales from table_1
union
select customer, info, 'b', offer_type_b_sales from table_1
union 
select customer, info, 'c', offer_type_c_sales from table_1

| 客户|信息|报价类型|销售|
| --|--|--|--|
| AA| X|一| 10 |
| AA| X| B| 20 |
| AA| X| C| 30 |
| BB| Y|一| 0 |
| BB| Y| B| 10 |
| BB| Y| C| 15 |
| CC| X|一| 20 |
| CC| X| B| 0 |
| CC| X| C| 30 |
如果你不想要零行,那就添加一个where子句。

rsl1atfo

rsl1atfo2#

实际上,您正在寻找的是与枢轴操作相反的操作。我为你准备了一个MSSQL的例子。
您可以使用UNPIVOT来执行此操作

/*Data Creation*/
Create Table #talbe_1(
    customer Nvarchar(max),
    info Nvarchar(max),
    offer_type_a_sales int,
    offer_type_b_sales int,
    offer_type_c_sales int
)

insert into #talbe_1 (customer, info, offer_type_a_sales, offer_type_b_sales, offer_type_c_sales)
Values ('AA', 'X', 10, 20, 30)
insert into #talbe_1 (customer, info, offer_type_a_sales, offer_type_b_sales, offer_type_c_sales)
Values ('BB', 'Y', 0, 10, 15)
insert into #talbe_1 (customer, info, offer_type_a_sales, offer_type_b_sales, offer_type_c_sales)
Values ('CC', 'X', 20, 0, 30)
/*Data Creation*/

/*Solution*/
SELECT customer, info, (CASE offertype When 'offer_type_a_sales' Then 'a' When 'offer_type_b_sales' Then 'b' When 'offer_type_c_sales' Then 'c' Else '-' End) as 'offertype', sales
FROM
    (SELECT customer, info, offer_type_a_sales, offer_type_b_sales, offer_type_c_sales FROM #talbe_1) p
UNPIVOT
   (sales FOR offertype IN (offer_type_a_sales, offer_type_b_sales, offer_type_c_sales)
) AS unpvt
WHERE sales > 0
/*Solution*/

Drop Table #talbe_1

UNPIVOT过程中,必须给予列标题。我使用CASEWHEN是因为它返回的值与这些列标题中的名称相同。
测试结果:
| 客户|信息|报价铅字|销售|
| --|--|--|--|
| AA| X|一| 10 |
| AA| X| B| 20 |
| AA| X| C| 30 |
| BB| Y| B| 10 |
| BB| Y| C| 15 |
| CC| X|一| 20 |
| CC| X| C| 30 |
联合的例子也很好,但你可能想用这个。
如果列是动态的,并且不是固定的;(offer_type_a_sales,offer_type_B_sales,offer_type_c_sales,offer_type_d_sales,offer_type_e_sales等)如果有这样的结构,您可以将其带入EXEC并在外部给予与列部分相对应的位置。补充资料。

ghg1uchk

ghg1uchk3#

Db2不支持UNPIVOT子句,但有一个替代解决方案。

WITH MYTAB (customer,   info,   offer_type_a_sales, offer_type_b_sales, offer_type_c_sales)
AS
(
VALUES
  ('AA',    'X',    10, 20, 30)
, ('BB',    'Y',    0,  10, 15)
, ('CC',    'X',    20, 0,  30)
)
SELECT
  T.customer
, T.info
, V.offer_type
, V.offer_type_sales
FROM MYTAB T
, TABLE 
(
  VALUES
    ('a', T.offer_type_a_sales)
  , ('b', T.offer_type_b_sales)
  , ('c', T.offer_type_c_sales)
) V (offer_type, offer_type_sales)

| 客户|信息|优惠类型|优惠_类型_销售|
| --|--|--|--|
| AA| X|一| 10 |
| AA| X| B| 20 |
| AA| X| C| 30 |
| BB| Y|一| 0 |
| BB| Y| B| 10 |
| BB| Y| C| 15 |
| CC| X|一| 20 |
| CC| X| B| 0 |
| CC| X| C| 30 |
fiddle

相关问题