2016-11-27 2 views
4

Я пытаюсь объединить разные строки в один, когда они имеют одинаковые идентификаторы, но разные значения столбцов.SQL Слияние двух строк с одинаковым идентификатором, но с разными значениями столбцов (Oracle)

Например:

(table1) 

    id  colour 

    1  red 
    1  blue 
    2  green 
    2  red 

Я хотел бы, чтобы это было комбинировать так, чтобы результат:

id  colour1 colour2 

    1  red  blue 
    2  green  red 

Или

id  colour 

    1  red, blue 
    2  green, red 

Или любой другой вариант выше, так что ряды каким-то образом соединены.

Любая помощь будет оценена! Заранее спасибо.

+0

ПОЧЕМУ вы хотите это сделать? Это строго и исключительно для целей отчетности, или вы хотите использовать результат для хранения данных и/или дальнейшей обработки? Если он предназначен исключительно для отчетности: это можно сделать в SQL, но лучше сделать это в приложении для отчетов, независимо от того, что вы используете. Если он предназначен для хранения и/или дальнейшей обработки, это идея TERRIBLE. Данные в настоящее время находятся в «первой нормальной форме». Вы ищете что-то, что нарушает первую нормальную форму - вы идете к очень плохо ошибочной модели данных. – mathguy

+0

Я отредактировал ваше сообщение, чтобы удалить тег 'merge'; 'merge' - это нечто совершенно иное и не связанное с вашей проблемой, оно связано с обновлением, вставкой и удалением в/из целевой таблицы с использованием данных в исходной таблице. – mathguy

+0

Я упростил таблицу, чтобы получить более простой ответ, в действительности обе колонки вместе являются первичным ключом, а также внешними ключами. – LEJ

ответ

1

Пожалуйста, сначала прочитайте мой комментарий - вы не должны даже думать об этом, если он не предназначен только для целей отчетности, и вы хотите посмотреть, как это можно сделать в простом SQL (в отличие от правильного решения, которое использовать инструмент отчетности для этой работы).

Второй формат является самым простым, особенно если вы не заботитесь о том порядке, в котором появляются цвета:

select id, listagg(colour, ', ') within group (order by null) 
from  table1 
group by id 

order by null означает порядок в случайном порядке. Если вы хотите заказать что-то еще, используйте это в order by с listagg(). Например, чтобы упорядочить цвета в алфавитном порядке, вы можете сказать within group (order by colour).

Для первого формата вам необходимо иметь априорное ограничение на количество столбцов, и как вы это делаете, зависит от используемой вами версии Oracle (которую вы всегда должны включать в каждый вопрос, который вы публикуете здесь, и на других досках обсуждений). Эта концепция называется «поворотным»; начиная с версии 11, Oracle имеет явный оператор PIVOT, который вы можете использовать.

+0

Отлично работает, спасибо! Да, просто посмотреть, как это делается в SQL. – LEJ

2

Следующие действия решат вашу проблему в первом из двух способов, которые вы предложили. Listagg является то, что вы будете использовать, чтобы решить это второй из двух способов (как отмечалось в другой ответ):

select id, 
      min(decode(rn,1,colour,null)) as colour1, 
      min(decode(rn,2,colour,null)) as colour2, 
      min(decode(rn,3,colour,null)) as colour3 
from (
     select id, 
      colour, 
      row_number() over(partition by id order by colour) as rn 
     from table1 
    ) 
group by id; 

При таком подходе вам необходимо добавить дополнительные заявления случае до максимального числа возможных цвета для данного идентификатора (это решение не является динамическим).

Кроме того, это помещает цвета в color1, color2 и т. Д., Основанные на алфавитном порядке имен цветов. Если вы предпочитаете случайный заказ или какой-либо другой заказ, вам необходимо изменить order by.

+0

Это будет работать, если будет гарантировано, что для каждого идентификатора всегда будет не более трех цветов (и это предположение было бы лучше всего указано в ответе). Я бы также добавил комментарий о «порядке по цвету» (аналогично комментарию в «другом ответе»). – mathguy

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

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