Reputation: 8074
I have two tables trackings
and responses
. I am running the query below to join the two tables based on the case/code_2 columns.
Because there will sometimes be multiple records in the response
table for every record in the trackings
table, I only wanted one row returned, not duplicates for each row in the response table as would normally happen.
I accomplished this using the query below which works great.
SELECT T0.timestamp AS 'Creation Date', T0.ipaddress, T0.code_1 AS 'Alias', T0.code_2 AS 'Case ID', COUNT(T0.ipaddress) AS each_amount, T0.first, MAX(T1.res_id) AS 'responses'
FROM `trackings` AS T0
LEFT JOIN `responses` AS T1
ON T0.code_2 = T1.case
JOIN (
SELECT T2.case, MAX(T2.timestamp) AS max_date
FROM `responses` AS T2
GROUP BY T2.case
) x_temp_response_table
ON x_temp_response_table.case = T1.case
AND x_temp_response_table.max_date = T1.timestamp
WHERE T0.timestamp >= '2014-04-20 00:00:00'
AND T0.timestamp <= '2014-04-30 23:59:59'
GROUP BY code_2
However because of the second join to limit the response rows to just one, it now doesn't return trackings
rows when there is no corresponding record in the response table.
Basically before adding this second join, it would return all rows from the trackings
table, and just stick a NULL in the 'responses' column if there was no corresponding row in the responses
table <- This is probably obvious as it's what a left join does :-)
So ideally I would like the query above to still return all rows from the trackings
table even if there is no corresponding row in the responses table.
Any help would be really appreciated.
Upvotes: 0
Views: 227
Reputation: 6844
Try below query hope it will provide you desired results:
SELECT T0.timestamp AS 'Creation Date', T0.ipaddress, T0.code_1 AS 'Alias', T0.code_2 AS 'Case ID', COUNT(T0.ipaddress) AS each_amount, T0.first, MAX(T1.res_id) AS 'responses'
FROM `trackings` AS T0
LEFT JOIN
(
SELECT `case`,res_id FROM
(SELECT `case`,res_id FROM `responses` ORDER BY `timestamp` DESC) T2
GROUP BY `case`
) T1
ON T0.code_2 = T1.case
WHERE T0.timestamp >= '2014-04-20 00:00:00'
AND T0.timestamp <= '2014-04-30 23:59:59'
GROUP BY code_2;
Upvotes: 1
Reputation: 60462
This is untested, but moving the responses
join into a Derived Table should work:
SELECT T0.timestamp AS 'Creation Date', T0.ipaddress, T0.code_1 AS 'Alias', T0.code_2 AS 'Case ID', COUNT(T0.ipaddress) AS each_amount, T0.first, MAX(T1.res_id) AS 'responses'
FROM `trackings` AS T0
LEFT JOIN
(
SELECT T1.case, T1.res_id
FROM `responses` AS T1
JOIN
(
SELECT T2.CASE, MAX(T2.TIMESTAMP) AS max_date
FROM `responses` AS T2
GROUP BY T2.CASE
) x_temp_response_table
ON x_temp_response_table.CASE = T1.CASE
AND x_temp_response_table.max_date = T1.TIMESTAMP
) AS T1
ON T0.code_2 = T1.CASE
WHERE T0.TIMESTAMP >= '2014-04-20 00:00:00'
AND T0.timestamp <= '2014-04-30 23:59:59'
GROUP BY code_2
Upvotes: 1
Reputation: 60493
You may do this with an awful subquery (not as performant, but)...
SELECT
T0.timestamp AS 'Creation Date',
T0.ipaddress, T0.code_1 AS 'Alias',
T0.code_2 AS 'Case ID',
COUNT(T0.ipaddress) AS each_amount,
T0.first,
(SELECT r.res_id from responses r
where r.case = T0.code_2
order by r.timestamp desc
LIMIT 1) as responses
FROM `trackings` AS T0
WHERE T0.timestamp >= '2014-04-20 00:00:00'
AND T0.timestamp <= '2014-04-30 23:59:59'
GROUP BY code_2
Upvotes: 1