Reputation: 536
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 |
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 |
As you can tell from the queries, both tables have a "com_id"
column. 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. I'll appreciate your help guys.
Upvotes: 0
Views: 2699
Reputation: 35563
Not sure if the com_id will be equal or not, but in case they might not be then I suggest this:
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
Upvotes: 2
Reputation: 94884
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
). For this SMS you want the sender's name. This query results in one or zero rows depending on whether the last communication was an SMS.
Second query: You want the last SMSs for the last SMS communication this time identified by MAX(cs.com_id)
. 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? 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? This doesn't seem likely. I guess you rather want either
for both the sender and recipient. Or can you have non-SMS communications with SMSs attatched?
Here is a query for the last SMS communication:
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;
Upvotes: 0
Reputation: 1030
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.
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
Upvotes: 0