每行到列值
Each rows to column values
我正在尝试创建一个视图,该视图显示第一个 table 的列以及第二个 table 的前 3 条记录(按日期排序在 1 行中)。
我尝试使用子 table 的偏移量 select 特定行并连接到主 table,但是当连接查询结果按日期排序时,没有
WHERE tblMain_id = ..
条款加入SQL它returns错误记录。
这是 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 |
您可以使用条件聚合:
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;
Here 是 SQL Fiddle.
这是一个应该能满足您期望的解决方案。
这是通过首先对每个 table 中的记录进行排名并将它们连接在一起来实现的。然后,外部查询使用聚合生成预期的输出。
即使主 table 中的第一条记录没有 ID 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
我正在尝试创建一个视图,该视图显示第一个 table 的列以及第二个 table 的前 3 条记录(按日期排序在 1 行中)。
我尝试使用子 table 的偏移量 select 特定行并连接到主 table,但是当连接查询结果按日期排序时,没有
WHERE tblMain_id = ..
条款加入SQL它returns错误记录。
这是 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 |
您可以使用条件聚合:
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;
Here 是 SQL Fiddle.
这是一个应该能满足您期望的解决方案。
这是通过首先对每个 table 中的记录进行排名并将它们连接在一起来实现的。然后,外部查询使用聚合生成预期的输出。
即使主 table 中的第一条记录没有 ID 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