简体   繁体   English

将两个具有不同数据类型和列数的SELECT语句合并到PostgreSQL中的一个输出中

[英]Merge two SELECT statements with different data types and number of columns into one output in PostgreSQL

I have two queries. 我有两个查询。 The first - 首先 -

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)

which basically outputs - | message_date | message_text | message_by | 它基本上输出- | message_date | message_text | message_by | | message_date | message_text | message_by |

And the second query - 第二个查询-

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

which outputs - | com_id | recipient_name | phone_number | 其输出- | com_id | recipient_name | phone_number | | com_id | recipient_name | phone_number |

As you can tell from the queries, both tables have a "com_id" column. 从查询中可以看出,两个表都有一个"com_id"列。 What I need is to make a single query that will merge the two queries above to get a single output, something like - 我需要做一个查询,将上面的两个查询合并以获得一个输出,例如-

|message_date|message_text|message_by|recipient_name|phone_number|

How can I achieve that? 我该如何实现? I can't use UNION because of the different data types and different number of columns. 由于数据类型和列数不同,因此无法使用UNION I'll appreciate your help guys. 谢谢您的帮助。

Not sure if the com_id will be equal or not, but in case they might not be then I suggest this: 不知道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

Note a small amount of repetition could be avoided by using CTEs 请注意,使用CTE可以避免少量重复

Is there a reason why you would need to union or join? 有什么理由需要工会或加入工会? In the context you are asking the question com_id should not matter. 在上下文中,您提出的问题com_id应该无关紧要。

Try something like this, ( this query is nothing special basically just merged the two together ) 尝试这样的事情,(此查询基本上没有什么特别的,只是将两者合并在一起)

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

First query: You want the last communication identified by MAX(c.com_id) , but only in case it is an SMS ( c.send_as_sms = TRUE ). 第一个查询:您想要由MAX(c.com_id)标识的最后一个通信,但是仅在它是SMS的情况下( c.send_as_sms = TRUE )。 For this SMS you want the sender's name. 对于此SMS,您需要发件人的姓名。 This query results in one or zero rows depending on whether the last communication was an SMS. 根据最后一次通信是否是SMS,此查询将导致一行或零行。

Second query: You want the last SMSs for the last SMS communication this time identified by MAX(cs.com_id) . 第二个查询:您希望这次由MAX(cs.com_id)标识的最后一次SMS通信的最后一个SMS。 This looks redundant. 这看起来多余。 Why do you have a send_as_sms in communications when you see from the existence of matching communication_sms records that this is an SMS? 当从匹配的communication_sms记录的存在中看到这是SMS时,为什么在communicationssend_as_sms You may want to think over this design. 您可能需要考虑这种设计。 Anyway, from this you want to get the recipient's name plus some phone number. 无论如何,您要从中获取收件人的姓名以及一些电话号码。

How to combine the two queries is not evident. 如何结合这两个查询尚不清楚。 Do you really want the latest SMSs with the recipients' names, but only add the sender's name in case this last SMS is also the last communication? 您是否真的想要带有收件人姓名的最新SMS,但仅添加发件人的姓名,以防最后一条SMS也是最后一次通信? This doesn't seem likely. 这似乎不太可能。 I guess you rather want either 我想你宁愿

  1. the lastest communication in case its an SMS or 如果是SMS,则为最新通讯
  2. the latest SMS communication 最新的短信通讯

for both the sender and recipient. 对于发件人和收件人。 Or can you have non-SMS communications with SMSs attatched? 还是可以让非SMS通信与SMS相连?

Here is a query for the last SMS communication: 这是最后一次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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM