限制在MySQL问题中左连接中返回的行

时间:2014-05-07 10:17:52

标签: mysql sql join left-join

我有两张表trackingsresponses。我正在运行下面的查询,根据case / code_2列连接两个表。

因为response表中有时会为trackings表中的每个记录存在多条记录,所以我只希望返回一行,而不是通常会发生响应表中每一行的重复行

我使用下面的查询完成了这项工作,效果很好。

    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

但是,由于第二次连接将响应行限制为仅一个,因此当响应表中没有相应的记录时,它现在不会返回trackings行。

基本上在添加第二个连接之前,它将返回trackings表中的所有行,如果responses表中没有相应的行,则只在“响应”列中粘贴一个NULL ; - 这可能很明显,因为这是左连接的作用: - )

理想情况下,即使响应表中没有相应的行,我仍希望上面的查询仍返回trackings表中的所有行。

任何帮助都会非常感激。

3 个答案:

答案 0 :(得分:1)

你可能会用一个糟糕的子查询(不是高效的,但是)......

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

答案 1 :(得分:1)

这是未经测试的,但将responses联接移动到派生表应该有效:

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

答案 2 :(得分:1)

尝试以下查询希望它能为您提供所需的结果:

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;