oracle中列转行
convert column to row in oracle
我有一个问题,有什么方法可以将列转换为行。
例如,我有一个这样的 table:
CREATE TABLE mytable(u_id, month, offer, revenue) as
SELECT 1, 'January', 'Offer_1', 45 FROM dual
UNION ALL
SELECT 1, 'February','Offer_2', 40 FROM dual
UNION ALL
SELECT 1, 'March' ,'Offer_1', 35 FROM dual
UNION ALL
SELECT 2, 'January' ,'Offer_2', 40 FROM dual
UNION ALL
SELECT 2, 'February','Offer_3', 40 FROM dual
UNION ALL
SELECT 2, 'March' ,'Offer_1', 50 FROM dual;
我的预期 table 是
(每个用户应该一行)
u_id
january_offer
january_revenue
february_offer
february_revenue
march_offer
march_revenue
1
Offer_1
45
Offer_2
40
Offer_1
35
2
Offer_2
40
Offer_3
40
Offer_1
50
我试过了:
SELECT t1.u_id,
t1.january_offer,
t1.january_revenue,
t2.february_offer,
t2.february_revenue,
t3.march_offer,
t3.march_revenue
FROM (SELECT u_id, offer AS january_offer,
revenue AS january_revenue
FROM mytable
WHERE month = 'January') t1
LEFT JOIN (SELECT u_id,
offer AS february_offer,
revenue AS february_revenue
FROM mytable t1
WHERE month = 'February') t2
ON t1.u_id = t2.u_id
LEFT JOIN (SELECT u_id, offer AS march_offer,
revenue AS march_revenue
FROM mytable t1
WHERE month = 'March') t3
ON t2.u_id = t3.u_id
但是,真的,我有很多数据和一个很长的 SQL 脚本,这种方法加重了我的脚本。
您可以将条件聚合与 CASE..WHEN
表达式一起使用,例如
SELECT u_id,
MAX(CASE WHEN month = 'January' THEN offer END) AS january_offer,
MAX(CASE WHEN month = 'January' THEN revenue END) AS january_revenue,
MAX(CASE WHEN month = 'February' THEN offer END) AS february_offer,
MAX(CASE WHEN month = 'February' THEN revenue END) AS february_revenue,
MAX(CASE WHEN month = 'March' THEN offer END) AS march_offer,
MAX(CASE WHEN month = 'March' THEN revenue END) AS march_revenue
FROM t
GROUP BY u_id
或使用DECODE()
函数,例如
SELECT u_id,
MAX(DECODE (month , 'January', offer)) AS january_offer,
MAX(DECODE (month , 'January', revenue)) AS january_revenue,
MAX(DECODE (month , 'February', offer)) AS february_offer,
MAX(DECODE (month , 'February', revenue)) AS february_revenue,
MAX(DECODE (month , 'March', offer)) AS march_offer,
MAX(DECODE (month , 'March', revenue)) AS march_revenue
FROM t
GROUP BY u_id
另一种可能更有效的模式是使用 case 表达式:
SELECT t1.u_id
, CASE month WHEN 'January' then offer END AS january_offer
, CASE month WHEN 'January' then revenue END AS january_revenue
, CASE month WHEN 'February' then offer END AS february_offer
, ...
从那里您可以使用聚合函数来消除空行:
SELECT u_id
, MAX(january_offer) AS january_offer
, MAX(january_revenue) AS january_revenue
, MAX(february_offer) AS february_offer
, ...
FROM (
SELECT t1.u_id
, CASE month WHEN 'January' then offer END AS january_offer
, CASE month WHEN 'February' then offer END AS february_offer
, ...
) AS t
GROUP BY u_id
一般来说,这种操作在应用程序的表示层比在数据库层处理得更好。
这就是 PIVOT
的设计目的:
SELECT *
FROM package
PIVOT (
MAX(offer) AS offer, MAX(revenue) AS revenue
FOR month IN ( 'January' AS january, 'February' AS feburary, 'March' AS march )
)
其中,对于示例数据:
CREATE TABLE package (U_id, month, offer,revenue) AS
SELECT 1, 'January', 'offer_1', 45 FROM DUAL UNION ALL
SELECT 1, 'February', 'offer_2', 40 FROM DUAL UNION ALL
SELECT 1, 'March', 'offer_1', 35 FROM DUAL UNION ALL
SELECT 2, 'January', 'offer_2', 40 FROM DUAL UNION ALL
SELECT 2, 'February', 'offer_3', 40 FROM DUAL UNION ALL
SELECT 2, 'March', 'offer_1', 50 FROM DUAL;
输出:
U_ID
JANUARY_OFFER
JANUARY_REVENUE
FEBURARY_OFFER
FEBURARY_REVENUE
MARCH_OFFER
MARCH_REVENUE
1
offer_1
45
offer_2
40
offer_1
35
2
offer_2
40
offer_3
40
offer_1
50
db<>fiddle here
我有一个问题,有什么方法可以将列转换为行。 例如,我有一个这样的 table:
CREATE TABLE mytable(u_id, month, offer, revenue) as
SELECT 1, 'January', 'Offer_1', 45 FROM dual
UNION ALL
SELECT 1, 'February','Offer_2', 40 FROM dual
UNION ALL
SELECT 1, 'March' ,'Offer_1', 35 FROM dual
UNION ALL
SELECT 2, 'January' ,'Offer_2', 40 FROM dual
UNION ALL
SELECT 2, 'February','Offer_3', 40 FROM dual
UNION ALL
SELECT 2, 'March' ,'Offer_1', 50 FROM dual;
我的预期 table 是
(每个用户应该一行)
u_id | january_offer | january_revenue | february_offer | february_revenue | march_offer | march_revenue |
---|---|---|---|---|---|---|
1 | Offer_1 | 45 | Offer_2 | 40 | Offer_1 | 35 |
2 | Offer_2 | 40 | Offer_3 | 40 | Offer_1 | 50 |
我试过了:
SELECT t1.u_id,
t1.january_offer,
t1.january_revenue,
t2.february_offer,
t2.february_revenue,
t3.march_offer,
t3.march_revenue
FROM (SELECT u_id, offer AS january_offer,
revenue AS january_revenue
FROM mytable
WHERE month = 'January') t1
LEFT JOIN (SELECT u_id,
offer AS february_offer,
revenue AS february_revenue
FROM mytable t1
WHERE month = 'February') t2
ON t1.u_id = t2.u_id
LEFT JOIN (SELECT u_id, offer AS march_offer,
revenue AS march_revenue
FROM mytable t1
WHERE month = 'March') t3
ON t2.u_id = t3.u_id
但是,真的,我有很多数据和一个很长的 SQL 脚本,这种方法加重了我的脚本。
您可以将条件聚合与 CASE..WHEN
表达式一起使用,例如
SELECT u_id,
MAX(CASE WHEN month = 'January' THEN offer END) AS january_offer,
MAX(CASE WHEN month = 'January' THEN revenue END) AS january_revenue,
MAX(CASE WHEN month = 'February' THEN offer END) AS february_offer,
MAX(CASE WHEN month = 'February' THEN revenue END) AS february_revenue,
MAX(CASE WHEN month = 'March' THEN offer END) AS march_offer,
MAX(CASE WHEN month = 'March' THEN revenue END) AS march_revenue
FROM t
GROUP BY u_id
或使用DECODE()
函数,例如
SELECT u_id,
MAX(DECODE (month , 'January', offer)) AS january_offer,
MAX(DECODE (month , 'January', revenue)) AS january_revenue,
MAX(DECODE (month , 'February', offer)) AS february_offer,
MAX(DECODE (month , 'February', revenue)) AS february_revenue,
MAX(DECODE (month , 'March', offer)) AS march_offer,
MAX(DECODE (month , 'March', revenue)) AS march_revenue
FROM t
GROUP BY u_id
另一种可能更有效的模式是使用 case 表达式:
SELECT t1.u_id
, CASE month WHEN 'January' then offer END AS january_offer
, CASE month WHEN 'January' then revenue END AS january_revenue
, CASE month WHEN 'February' then offer END AS february_offer
, ...
从那里您可以使用聚合函数来消除空行:
SELECT u_id
, MAX(january_offer) AS january_offer
, MAX(january_revenue) AS january_revenue
, MAX(february_offer) AS february_offer
, ...
FROM (
SELECT t1.u_id
, CASE month WHEN 'January' then offer END AS january_offer
, CASE month WHEN 'February' then offer END AS february_offer
, ...
) AS t
GROUP BY u_id
一般来说,这种操作在应用程序的表示层比在数据库层处理得更好。
这就是 PIVOT
的设计目的:
SELECT *
FROM package
PIVOT (
MAX(offer) AS offer, MAX(revenue) AS revenue
FOR month IN ( 'January' AS january, 'February' AS feburary, 'March' AS march )
)
其中,对于示例数据:
CREATE TABLE package (U_id, month, offer,revenue) AS
SELECT 1, 'January', 'offer_1', 45 FROM DUAL UNION ALL
SELECT 1, 'February', 'offer_2', 40 FROM DUAL UNION ALL
SELECT 1, 'March', 'offer_1', 35 FROM DUAL UNION ALL
SELECT 2, 'January', 'offer_2', 40 FROM DUAL UNION ALL
SELECT 2, 'February', 'offer_3', 40 FROM DUAL UNION ALL
SELECT 2, 'March', 'offer_1', 50 FROM DUAL;
输出:
U_ID JANUARY_OFFER JANUARY_REVENUE FEBURARY_OFFER FEBURARY_REVENUE MARCH_OFFER MARCH_REVENUE 1 offer_1 45 offer_2 40 offer_1 35 2 offer_2 40 offer_3 40 offer_1 50
db<>fiddle here