Каждый ряд значений столбца - PullRequest
2 голосов
/ 20 сентября 2019

Я пытаюсь создать представление, которое показывает столбцы первой таблицы плюс первые 3 записи второй таблицы, отсортированные по дате в 1 строке.

Я пытался выбрать определенные строки, используя смещение из вложенной таблицы и присоединиться к основной таблице, но при объединении результата запроса упорядочивается по дате, без предложения

WHERE tblMain_id = ..

при присоединении к SQL возвращается неправильныйrecord.

Вот пример sqlfiddle: sqlfiddle demo

tblMain

| id | fname | lname | salary |
+----+-------+-------+--------+
|  1 |  John |   Doe |   1000 |
|  2 |   Bob |  Ross |   5000 |
|  3 |  Carl | Sagan |   2000 |
|  4 | Daryl | Dixon |   3000 |

tblSub

| id |           email |  emaildate | tblmain_id |
+----+-----------------+------------+------------+
|  1 |   John@Doe1.com | 2019-01-01 |          1 |
|  2 |   John@Doe2.com | 2019-01-02 |          1 |
|  3 |   John@Doe3.com | 2019-01-03 |          1 |
|  4 |   Bob@Ross1.com | 2019-02-01 |          2 |
|  5 |   Bob@Ross2.com | 2018-12-01 |          2 |
|  6 |  Carl@Sagan.com | 2019-10-01 |          3 |
|  7 | Daryl@Dixon.com | 2019-11-01 |          4 |

Просмотр Я пытаюсь достичь:

| id | fname | lname | salary |       email_1 | emaildate_1 |       email_2 | emaildate_2 |       email_3 | emaildate_3 |
+----+-------+-------+--------+---------------+-------------+---------------+-------------+---------------+-------------+
|  1 |  John |   Doe |   1000 | John@Doe1.com |  2019-01-01 | John@Doe2.com |  2019-01-02 | John@Doe3.com |  2019-01-03 |

Просмотр, который я создал

| id | fname | lname | salary | email_1 | emaildate_1 |       email_2 | emaildate_2 |       email_3 | emaildate_3 |
+----+-------+-------+--------+---------+-------------+---------------+-------------+---------------+-------------+
|  1 |  John |   Doe |   1000 |  (null) |      (null) | John@Doe1.com |  2019-01-01 | John@Doe2.com |  2019-01-02 |

Ответы [ 2 ]

1 голос
/ 20 сентября 2019

Вы можете использовать условное агрегирование:

select m.id, m.fname, m.lname, m.salary,
       max(s.email) filter (where seqnum = 1) as email_1,
       max(s.emailDate) filter (where seqnum = 1) as emailDate_1,
       max(s.email) filter (where seqnum = 2) as email_2,
       max(s.emailDate) filter (where seqnum = 3) as emailDate_2,
       max(s.email) filter (where seqnum = 3) as email_3,
       max(s.emailDate) filter (where seqnum = 3) as emailDate_3
from tblMain m left join
     (select s.*,
             row_number() over (partition by tblMain_id order by emailDate desc) as seqnum
      from tblsub s
     ) s
     on s.tblMain_id = m.id           
where m.id = 1
group by m.id, m.fname, m.lname, m.salary;

Здесь - это скрипта SQL.

0 голосов
/ 20 сентября 2019

Вот решение, которое должно дать вам то, что вы ожидаете.

Это работает путем ранжирования записей в каждой таблице и объединения их вместе.Затем внешний запрос использует агрегацию для генерации ожидаемого результата.

Это решение будет работать, даже если первая запись в основной таблице не имеет идентификатора 1.Кроме того, фильтрация выполняется в пределах JOIN с, поэтому это должно быть достаточно эффективным.

SELECT
    m.id,
    m.fname,
    m.lname,
    m.salary,
    MAX(CASE WHEN s.rn = 1 THEN s.email END) email_1,
    MAX(CASE WHEN s.rn = 1 THEN s.emaildate  END) email_date1,
    MAX(CASE WHEN s.rn = 2 THEN s.email END) email_2,
    MAX(CASE WHEN s.rn = 2 THEN s.emaildate  END) email_date2,
    MAX(CASE WHEN s.rn = 3 THEN s.email END) email_3,
    MAX(CASE WHEN s.rn = 3 THEN s.emaildate  END) email_date3
FROM 
    (
        SELECT m.*, ROW_NUMBER() OVER(ORDER BY id) rn
        FROM tblMain
    ) m
    INNER JOIN (
        SELECT 
            email, 
            emaildate, 
            ROW_NUMBER() OVER(PARTITION BY id ORDER BY emaildate) rn
        FROM tblSub

    ) s 
    ON m.id = s.tblmain_id 
    AND m.rn = 1 
    AND s.rn <= 3
GROUP BY 
    m.id,
    m.fname,
    m.lname,
    m.salary
...