Создание выходных данных SQL в определенном формате

#sql #oracle

Вопрос:

Существует две таблицы базы данных. Например:

  1. Пользователь:-
    Идентификатор пользователя Имя
    1 Мистер А
    2 Г-н Б.
  2. Подробности по электронной почте:-
    Идентификатор электронной почты Идентификатор пользователя Электронная почта
    1 1 safk@as.com
    2 1 asdfk@ad.com
    3 2 wqe@sda.com

Я хочу сгенерировать результат с помощью SQL-запроса Oracle в следующем формате:-

 |User ID | Name |  Email1    | Email2     |
| -------|------|------------|------------|
| 1      | Mr. A| safk@as.com|asdfk@ad.com|
| 2      | Mr. B| wqe@sda.com|            |
 

(У пользователя может быть любое количество электронных писем.)

_________ создание операторов таблицы

 create table Users(
  UserId int,
  Name varchar2(50)
);

create table emailDetails(
  EmailId int,
  UserId int,
  Email varchar2(50)
  );

insert into Users(UserId, Name) values (1, 'Mr A');
insert into Users(UserId, Name) values (2, 'Mr B');
insert into EmailDetails(EmailId, UserId, Email) values(1,1,'safk@as.com');
insert into EmailDetails(EmailId, UserId, Email) values(2,1,'asdfk@ad.com');
insert into EmailDetails(EmailId, UserId, Email) values(3,2,'wqe@sda.com');
 

Комментарии:

1. Хорошо, а вы уже пробовали что-нибудь и обнаружили какие-либо конкретные проблемы? ТАК что это не служба написания кода.

2. (1) Тег с базой данных, которую вы используете. (2) Из вашего вопроса я заключаю, что если у пользователя более двух электронных писем, вы произвольно хотите, чтобы в результирующем наборе было два.

3. @underscore_d, я нашел решение с помощью функции listagg, которая помещает несколько идентификаторов электронной почты в один столбец. Но я хочу поместить каждый идентификатор электронной почты в разные столбцы,такие как email1, email2 и т. Д.

Ответ №1:

если вам разрешено иметь один столбец «электронные письма» со списком, разделенным запятыми, вы можете использовать listagg. если вам нужно динамическое количество столбцов, вам нужно будет использовать динамический sql.

вот решение с одной колонкой под названием электронные письма

 SELECT
    u.userId, name,
    LISTAGG(email,', ') WITHIN GROUP(ORDER BY u.userId) AS emails
from users u 
join emaildetails e on(u.userId = e.Userid)
GROUP BY u.userId, name
ORDER BY u.userId;
 

вы можете запустить скрипку здесь
http://sqlfiddle.com/#!4/546eb/8

Ответ №2:

Если вы используете ROW_NUMBER аналитическую функцию, вы можете использовать ее в подзапросе в сочетании с некоторой группировкой.

   SELECT u.userid,
         u.name,
         MIN (CASE WHEN e.email_num = 1 THEN e.email END)     AS email1,
         MIN (CASE WHEN e.email_num = 2 THEN e.email END)     AS email2
    FROM users u
         LEFT JOIN
         (SELECT userid,
                 email,
                 ROW_NUMBER () OVER (PARTITION BY userid ORDER BY emailid)     AS email_num
            FROM emailDetails) e
             ON (u.userid = e.userid)
GROUP BY u.userid, u.name;