2016-07-18 2 views
2

Я довольно нового для SQL мира (2 дня), и я в основном имею три таблицы ниже (содержания таблиц изменились, но проблема по-прежнему тот же)Oracle: Преобразование нескольких строк, чтобы установить количество столбцов

Название Таблица

+----+-----------+ 
| ID | CHARACTER | 
+----+-----------+ 
| 1 | Bones  | 
+----+-----------+ 
| 2 | Booth  | 
+----+-----------+ 
| 3 | Angela | 
+----+-----------+ 
| 4 | Hodgins | 
+----+-----------+ 
| 5 | Sweets | 
+----+-----------+ 

Роли Таблица

+---------+------------+ 
| ROLE_ID | ROLE  | 
+---------+------------+ 
| A  | Squint  | 
+---------+------------+ 
| B  | Unemployed | 
+---------+------------+ 
| C  | Cop  | 
+---------+------------+ 
| D  | Young  | 
+---------+------------+ 
| E  | Crazy  | 
+---------+------------+ 
| F  | Smart  | 
+---------+------------+ 

NameAndRole Таблица

+--------------+----+---------+ 
| NAME_ROLE_ID | ID | ROLE_ID | 
+--------------+----+---------+ 
| 1   | 1 | A  | 
+--------------+----+---------+ 
| 2   | 1 | C  | 
+--------------+----+---------+ 
| 3   | 1 | E  | 
+--------------+----+---------+ 
| 4   | 1 | F  | 
+--------------+----+---------+ 
| 5   | 2 | C  | 
+--------------+----+---------+ 
| 6   | 3 | A  | 
+--------------+----+---------+ 
| 7   | 4 | A  | 
+--------------+----+---------+ 
| 8   | 4 | E  | 
+--------------+----+---------+ 

В результате я хочу это:

+----+-----------+--------+-------+-------+ 
| ID | CHARACTER | ROLE1 | ROLE2 | ROLE3 | 
+----+-----------+--------+-------+-------+ 
| 1 | Bones  | Squint | Cop | Crazy | 
+----+-----------+--------+-------+-------+ 
| 2 | Booth  | Cop |  |  | 
+----+-----------+--------+-------+-------+ 
| 3 | Angela | Squint |  |  | 
+----+-----------+--------+-------+-------+ 
| 4 | Hodgins | Squint | Crazy |  | 
+----+-----------+--------+-------+-------+ 
| 5 | Sweets |  |  |  | 
+----+-----------+--------+-------+-------+ 

Даже если имя технически может иметь более 3-х ролей, я просто хочу, чтобы напечатать первую 3. На основе бесчисленного Google поисков и чтения Oracle, я не понимаю, что мне нужно использовать LEFT JOIN, вложенный SELECT и PIVOT. У меня есть заявление ниже, но я знаю, что это не правильно, так как один, мне нужны символы в строке, а не в столбцах, что потенциально имеет место в pivot, и оператор не работает в Oracle с ошибкой:

)ON r. ROLE_ID = NameAndRole. ROLE_ID 
       * 
Error at line 15 
ORA-01748: only simple column names allowed here 

код:

SELECT n.ID, 
n.CHARACTER 

FROM Names n 

LEFT JOIN NameAndRole nr ON n.ID = nr.ID 
LEFT JOIN 
(
    (
    SELECT * 
    FROM Roles r 
    ) 
    PIVOT 
    (
     MAX(r.role) FOR NameAndRole.NAME_ROLE_ID IN (‘Bones’,’Booth’,’Angela’) 
     WHERE NameAndRole.NAME_ROLE_ID<3 

    ) 
)ON r. ROLE_ID = NameAndRole. ROLE_ID 

/*I’m not sure as to how much of this is garbage and what’s even usable at this point...*/ 

PS - Это мой первый вопрос на стек ничего так, если я не следовать некоторым хорошо известным правилам, не стесняйтесь, дайте мне знать.

+0

Всегда полезно включить полный стек ошибок, а не просто сказать, что оператор «не работает». Предполагая, что это означает, что вы получаете ошибку, а не запрос, но возвращает другой набор данных. –

+0

Спасибо, что сообщили мне! Я обновил сообщение с ошибкой, которую я получил после исправления ошибки, которую я заметил. – baymax

ответ

0

Я не уверен, что ваш запрос работал бы, даже если бы вы могли исправить ошибку. Я также не уверен на 100%, насколько хорошо бы работал pivot, так как ваши имена нужных столбцов не соответствуют значениям.

Тем не менее, вы можете достичь желаемых результатов, используя условную агрегацию и аналитическую функцию row_number. Кроме того, было бы очень просто добавить более трех ролей, если захотите.

select n.id, 
     n.character, 
     max(case when r.rn = 1 then r.role end) as role1, 
     max(case when r.rn = 2 then r.role end) as role2, 
     max(case when r.rn = 3 then r.role end) as role3 
    from names n 
    left join (select nr.id, 
        r.role, 
        row_number() over (
         partition by nr.id 
          order by nr.name_role_id) as rn 
       from NameAndRole nr 
       join roles r 
       on r.role_id = nr.role_id) r 
    on r.id = n.id 
group by n.id, n.character 
order by n.id 
+0

Извините за поздний ответ, но .. это сработало! Спасибо, много! – baymax

Смежные вопросы