簡體   English   中英

Oracle SQL-將N行的列值轉換為1行中的N列

[英]Oracle SQL - Convert N rows' column values to N columns in 1 row

與其他問題(例如“ Oracle將行轉換為列”)相比,此方法的竅門是我的列值是任意字符串,而不是我可用於解碼的東西。 進行以下查詢:

這里的描述表將人們的名字映射到描述,但是每個人可以有多個描述,例如“戴帽子”或“高”。

Select firstName, lastName, 
(Select description from descriptions --This can return any number of rows (0 or more)
 where description.firstName = people.firstName
 and description.lastName = people.lastName
 and rownum <= 3)
from people
where age >= 25;

我想要這樣的輸出:

FIRSTNAME LASTNAME DESCRIPTION1 DESCRIPTION2 DESCRIPTION3
Jeremy    Smith    Tall         Confused        (null)
Anne      Smith    (Null)       (Null)          (Null)
Mark      Davis    Short        Smart           Strong

在少於3個描述的情況下,我希望在那里為null。 對於3個以上的描述,我只想省略掉。

我正在使用Oracle 11.1。 可以有效地做到這一點嗎?

假設您不在乎描述以什么順序返回(即Jeremy Smith可以正確地將Description1或“ Confused”和Description2為“ Tall”),則只需要對行號進行旋轉即可。 如果您關心返回描述的順序,則可以在ROW_NUMBER分析函數的window函數中添加ORDER BY子句

SELECT firstName, 
       lastName,
       MAX( CASE WHEN rn = 1 THEN description ELSE NULL END ) description1,
       MAX( CASE WHEN rn = 2 THEN description ELSE NULL END ) description2,
       MAX( CASE WHEN rn = 3 THEN description ELSE NULL END ) description3
  FROM (SELECT firstName,
               lastName,
               description,
               row_number() over (partition by lastName, firstName) rn
          FROM descriptions
               JOIN people USING (firstName, lastName)
         WHERE age >= 25)
   GROUP BY firstname, lastname

順便說一句,我希望您實際上是在存儲一個出生日期並計算該人的年齡,而不是存儲年齡並假設人們每年都在更新自己的年齡。

我已經嘗試過此選項,但是它說我們應該在行分析功能內給出order by子句,如下所示,

row_number() over (partition by lastName, firstName order by lastName, firstName) rn

當我按order by子句時,它對我的​​情況很好用。

我的情況是用戶詳細信息在表A中,用戶組在表C中,並且用戶和用戶組之間的關聯在表B中。一個用戶可以有多個用戶組。 我需要在一行中包含多個用戶組的用戶名獲得結果

**

查詢:

**

SELECT username,
MAX( CASE WHEN rn = 1 THEN ugroup ELSE NULL END ) usergroup1,
MAX( CASE WHEN rn = 2 THEN ugroup ELSE NULL END ) usergroup2,
MAX( CASE WHEN rn = 3 THEN ugroup ELSE NULL END ) usergroup3, 
MAX( CASE WHEN rn = 4 THEN ugroup ELSE NULL END ) usergroup4,
MAX( CASE WHEN rn = 5 THEN ugroup ELSE NULL END ) usergroup5,
from (
select 
a.user_name username, 
c.name ugroup,
row_number() over (partition by a.user_name order by a.user_name) rn
from users a,
usergroupmembership b,
usergroups c
where a.USER_NAME in ('aegreen',
'esportspau'
)
and a.user_id= b.user_id
and b.group_id=c.group_id
)group by uname;

**

查詢結果

**

USERNAME    USERGROUP1  USERGROUP2  USERGROUP3  USERGROUP4  USERGROUP5
aegreen US_GOLF (null)  (null)  (null)  (null)
esportspau  EMEA - FSERVICE USER_ES_ES  EMEA-CR-ONLY    (null)  (null)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM