Вопрос

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.

Это было полезно?

Решение

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

Другие советы

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

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;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top