Oracle SQL:将行转换为多列
我正在使用Oracle11g,需要一种在select语句中将行转换为新的列组的方法。对于一些数据,我们正在过渡到1:3的关系,需要一种方法将其放入视图中。您能否帮助我们转换如下所示的数据:Oracle SQL:将行转换为多列,sql,oracle,oracle11g,pivot,Sql,Oracle,Oracle11g,Pivot,我正在使用Oracle11g,需要一种在select语句中将行转换为新的列组的方法。对于一些数据,我们正在过渡到1:3的关系,需要一种方法将其放入视图中。您能否帮助我们转换如下所示的数据: +---------+------------+ | User_Id | Station_Id | +---------+------------+ | 1 | 203 | | 1 | 204 | | 2 | 203 | |
+---------+------------+
| User_Id | Station_Id |
+---------+------------+
| 1 | 203 |
| 1 | 204 |
| 2 | 203 |
| 3 | 487 |
| 3 | 3787 |
| 3 | 738 |
+---------+------------+
为此:
+---------+-------------+-------------+---------------+
| User_Id | Station_One | Station_Two | Station_Three |
+---------+-------------+-------------+---------------+
| 1 | 203 | 204 | Null |
| 2 | 203 | Null | Null |
| 3 | 487 | 3787 | 738 |
+---------+-------------+-------------+---------------+
让我知道你还想要什么其他细节,并感谢你能给予的任何帮助 您可以使用
行编号
和自联接
:
with cte as
(
select userid, stationid,
row_number() over(partition by userid order by stationid) rn
from tbl
)
select distinct c1.userid,
c1.stationid station_one,
c2.stationid station_two,
c3.stationid station_three
from cte c1
left join cte c2 on c1.userid=c2.userid and c2.rn=2
left join cte c3 on c1.userid=c3.userid and c3.rn=3
where c1.rn=1
看
您还可以使用行号
和子查询
:
with cte as
(
select userid, stationid,
row_number() over(partition by userid order by stationid) rn
from tbl
)
select distinct userid,
(select stationid from cte c where c.userid=cte.userid and c.rn=1) station_one,
(select stationid from cte c where c.userid=cte.userid and c.rn=2) station_two,
(select stationid from cte c where c.userid=cte.userid and c.rn=3) station_three
from cte
请参见根据我的经验,实现这一点的最简单方法是使用条件聚合:
WITH mydata AS (
SELECT 1 AS user_id, 203 AS station_id FROM dual
UNION ALL
SELECT 1 AS user_id, 204 AS station_id FROM dual
UNION ALL
SELECT 2 AS user_id, 203 AS station_id FROM dual
UNION ALL
SELECT 3 AS user_id, 487 AS station_id FROM dual
UNION ALL
SELECT 3 AS user_id, 3787 AS station_id FROM dual
UNION ALL
SELECT 3 AS user_id, 738 AS station_id FROM dual
)
SELECT user_id
, MAX(CASE WHEN rn = 1 THEN station_id END) AS station_one
, MAX(CASE WHEN rn = 2 THEN station_id END) AS station_two
, MAX(CASE WHEN rn = 3 THEN station_id END) AS station_three
FROM (
SELECT user_id, station_id, ROW_NUMBER() OVER ( PARTITION BY user_id ORDER BY rownum ) AS rn
FROM mydata
) GROUP BY user_id;
只需将上述查询中的mydata
CTE替换为表名:
SELECT user_id
, MAX(CASE WHEN rn = 1 THEN station_id END) AS station_one
, MAX(CASE WHEN rn = 2 THEN station_id END) AS station_two
, MAX(CASE WHEN rn = 3 THEN station_id END) AS station_three
FROM (
SELECT user_id, station_id, ROW_NUMBER() OVER ( PARTITION BY user_id ORDER BY rownum ) AS rn
FROM mytable
) GROUP BY user_id;
嘿,大卫,谢谢你的回复。对不起,我的原始问题没有更具体。有数千个站点ID,因此您的解决方案对我来说不够动态。我不确定我是否了解我的答案中哪些不够动态-它与您接受的答案一样动态。