将具有不同数据类型和列数的两个 SELECT 语句合并为 PostgreSQL 中的一个输出
Merge two SELECT statements with different data types and number of columns into one output in PostgreSQL
我有两个问题。第一个-
SELECT
communications.creation_date as message_date,
message as message_text,
employees.first_name || ' ' || coalesce(employees.middle_name,'') || ' ' || employees.last_name as message_by
FROM app.communications
INNER JOIN app.employees ON communications.message_from = employees.emp_id
WHERE send_as_sms = TRUE AND com_id = (SELECT MAX(com_id) FROM app.communications)
基本上输出 - | message_date | message_text | message_by |
第二个查询 -
SELECT
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM app.communication_sms cs
WHERE cs.com_id = (SELECT MAX(cs2.com_id) FROM app.communication_sms cs2)
ORDER BY first_name ASC
输出 - | com_id | recipient_name | phone_number |
从查询中可以看出,两个表都有一个 "com_id"
列。我需要的是进行一个查询,该查询将合并上面的两个查询以获得单个输出,例如 -
|message_date|message_text|message_by|recipient_name|phone_number|
我怎样才能做到这一点?由于不同的数据类型和不同的列数,我不能使用 UNION
。我会感谢你们的帮助。
您需要联合或加入的原因是什么?在上下文中,你问的问题 com_id
应该无关紧要。
尝试这样的事情,(这个查询没什么特别的,基本上只是将两者合并在一起)
SELECT
communications.creation_date as message_date,
message as message_text,
employees.first_name || ' ' || coalesce(employees.middle_name,'') || ' ' || employees.last_name as message_by
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM app.communications, app.communication_sms cs
INNER JOIN app.employees ON communications.message_from = employees.emp_id
WHERE send_as_sms = TRUE AND com_id = (SELECT MAX(com_id) FROM app.communications)
AND cs.com_id = (SELECT MAX(cs2.com_id) FROM app.communication_sms cs2)
ORDER BY first_name ASC
不确定 com_id 是否相等,但如果它们可能不相等,我建议这样做:
select * -- list out the columns, I haven't bothered here
FROM (
SELECT MAX(com_id) as com_id FROM app.communications
UNION
SELECT MAX(cs2.com_id) FROM app.communication_sms cs2
) u
left join (
SELECT
com_id -- don't know which table this comes from
communications.creation_date as message_date,
message as message_text,
employees.first_name || ' ' || coalesce(employees.middle_name,'') || ' ' || employees.last_name as message_by
FROM app.communications
INNER JOIN app.employees ON communications.message_from = employees.emp_id
WHERE send_as_sms = TRUE AND com_id = (SELECT MAX(com_id) FROM app.communications)
) s1 on u.com_id = s1.com_id
left join (
SELECT
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM app.communication_sms cs
WHERE cs.com_id = (SELECT MAX(cs2.com_id) FROM app.communication_sms cs2)
ORDER BY first_name ASC
) s2 on u.com_id = s2.com_id
请注意,使用 CTE 可以避免少量重复
第一个查询: 您需要 MAX(c.com_id)
标识的最后一次通信,但前提是它是 SMS (c.send_as_sms = TRUE
)。对于此 SMS,您需要发件人的姓名。此查询会生成一行或零行,具体取决于上次通信是否为 SMS。
第二个查询:您想要本次由MAX(cs.com_id)
标识的最后一条短信通信的最后一条短信。这看起来多余。当你从存在匹配的 communication_sms
记录中看到这是一条短信时,为什么你在 communications
中有一个 send_as_sms
?您可能需要考虑一下这个设计。无论如何,从这里你想得到收件人的名字加上一些 phone 号码。
如何结合这两个查询并不明显。您真的想要包含收件人姓名的最新 SMS,但只添加发件人姓名以防最后一条 SMS 也是最后一次通信吗?这似乎不太可能。我猜你更想
- 最新通讯,如果是短信或
- 最新短信通讯
对于发件人和收件人。或者您可以通过附加 SMS 进行非 SMS 通信吗?
这里查询最后一次短信通讯:
SELECT
c.creation_date AS message_date,
c.message AS message_text,
e.first_name || ' ' || coalesce(e.middle_name,'') || ' ' || e.last_name AS message_by,
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM (SELECT * FROM app.communication_sms ORDER BY com_id DESC FETCH FIRST ROW ONLY) cs
JOIN app.communications c ON c.com_id = cs.com_id
JOIN app.employees e ON c.message_from = e.emp_id
ORDER cs.first_name ASC;
我有两个问题。第一个-
SELECT
communications.creation_date as message_date,
message as message_text,
employees.first_name || ' ' || coalesce(employees.middle_name,'') || ' ' || employees.last_name as message_by
FROM app.communications
INNER JOIN app.employees ON communications.message_from = employees.emp_id
WHERE send_as_sms = TRUE AND com_id = (SELECT MAX(com_id) FROM app.communications)
基本上输出 - | message_date | message_text | message_by |
第二个查询 -
SELECT
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM app.communication_sms cs
WHERE cs.com_id = (SELECT MAX(cs2.com_id) FROM app.communication_sms cs2)
ORDER BY first_name ASC
输出 - | com_id | recipient_name | phone_number |
从查询中可以看出,两个表都有一个 "com_id"
列。我需要的是进行一个查询,该查询将合并上面的两个查询以获得单个输出,例如 -
|message_date|message_text|message_by|recipient_name|phone_number|
我怎样才能做到这一点?由于不同的数据类型和不同的列数,我不能使用 UNION
。我会感谢你们的帮助。
您需要联合或加入的原因是什么?在上下文中,你问的问题 com_id
应该无关紧要。
尝试这样的事情,(这个查询没什么特别的,基本上只是将两者合并在一起)
SELECT
communications.creation_date as message_date,
message as message_text,
employees.first_name || ' ' || coalesce(employees.middle_name,'') || ' ' || employees.last_name as message_by
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM app.communications, app.communication_sms cs
INNER JOIN app.employees ON communications.message_from = employees.emp_id
WHERE send_as_sms = TRUE AND com_id = (SELECT MAX(com_id) FROM app.communications)
AND cs.com_id = (SELECT MAX(cs2.com_id) FROM app.communication_sms cs2)
ORDER BY first_name ASC
不确定 com_id 是否相等,但如果它们可能不相等,我建议这样做:
select * -- list out the columns, I haven't bothered here
FROM (
SELECT MAX(com_id) as com_id FROM app.communications
UNION
SELECT MAX(cs2.com_id) FROM app.communication_sms cs2
) u
left join (
SELECT
com_id -- don't know which table this comes from
communications.creation_date as message_date,
message as message_text,
employees.first_name || ' ' || coalesce(employees.middle_name,'') || ' ' || employees.last_name as message_by
FROM app.communications
INNER JOIN app.employees ON communications.message_from = employees.emp_id
WHERE send_as_sms = TRUE AND com_id = (SELECT MAX(com_id) FROM app.communications)
) s1 on u.com_id = s1.com_id
left join (
SELECT
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM app.communication_sms cs
WHERE cs.com_id = (SELECT MAX(cs2.com_id) FROM app.communication_sms cs2)
ORDER BY first_name ASC
) s2 on u.com_id = s2.com_id
请注意,使用 CTE 可以避免少量重复
第一个查询: 您需要 MAX(c.com_id)
标识的最后一次通信,但前提是它是 SMS (c.send_as_sms = TRUE
)。对于此 SMS,您需要发件人的姓名。此查询会生成一行或零行,具体取决于上次通信是否为 SMS。
第二个查询:您想要本次由MAX(cs.com_id)
标识的最后一条短信通信的最后一条短信。这看起来多余。当你从存在匹配的 communication_sms
记录中看到这是一条短信时,为什么你在 communications
中有一个 send_as_sms
?您可能需要考虑一下这个设计。无论如何,从这里你想得到收件人的名字加上一些 phone 号码。
如何结合这两个查询并不明显。您真的想要包含收件人姓名的最新 SMS,但只添加发件人姓名以防最后一条 SMS 也是最后一次通信吗?这似乎不太可能。我猜你更想
- 最新通讯,如果是短信或
- 最新短信通讯
对于发件人和收件人。或者您可以通过附加 SMS 进行非 SMS 通信吗?
这里查询最后一次短信通讯:
SELECT
c.creation_date AS message_date,
c.message AS message_text,
e.first_name || ' ' || coalesce(e.middle_name,'') || ' ' || e.last_name AS message_by,
cs.com_id,
cs.first_name ||' ' || cs.last_name AS recipient_name,
cs.sim_number AS phone_number
FROM (SELECT * FROM app.communication_sms ORDER BY com_id DESC FETCH FIRST ROW ONLY) cs
JOIN app.communications c ON c.com_id = cs.com_id
JOIN app.employees e ON c.message_from = e.emp_id
ORDER cs.first_name ASC;