使用LEFT JOIN的MySQL DISTINCT查询按主键选择重复的行

时间:2017-02-01 14:59:55

标签: mysql

我要做的是阻止MySQL通过表主键选择重复的行。

请注意,数据不是真实的,只是为了提问。

SELECT prospect_evaluations.*,
       prospect_evaluations_actions.evaluation_id,
       prospect_evaluations_actions.created_at AS lastaction_created_at
FROM `prospect_evaluations`
LEFT JOIN `prospect_evaluations_actions` ON `prospect_evaluations_actions`.`evaluation_id` = `prospect_evaluations`.`id`
WHERE `prospect_evaluations`.`category` = 'to_contact'
  AND `archived_at` IS NULL
  AND `discarded_at` IS NULL
  AND `prospect_evaluations`.`hidden_at` IS NULL
ORDER BY IFNULL( CAST(prospect_evaluations_actions.created_at AS date), CAST(prospect_evaluations.created_at AS date) ) DESC, `prospect_evaluations`.`priority` DESC
id | category   | archived_at | discarded_at | hidden_at | lastaction_created_at
1  | to_contact |      null   |         null |   null    | 01-02-2017 01:00:00
1  | to_contact |      null   |         null |   null    | 01-02-2017 02:00:00
2  | to_contact |      null   |         null |   null    | 01-02-2017 03:00:00

查询结果是什么?

id | category   | archived_at | discarded_at | hidden_at | lastaction_created_at
1  | to_contact |      null   |         null |   null    | 01-02-2017 02:00:00
2  | to_contact |      null   |         null |   null    | 01-02-2017 03:00:00

我想要的是什么?

00:00:00

编辑:我刚刚注意到结果是重复的,这取决于他们与评估相关联的行动数量,例如,如果评估在历史记录中有四个动作,那么它将被重复四次。我只需要LAST操作,以便我可以选择创建日期并使用它来订购我的条目!

编辑2:与被标记为可能重复的内容相比,这种情况有所不同,因为这个问题包括:

  • 选择table1
  • 表2的LEFT JOIN。

重复的问题包括:

  • 选择table1
  • table1的LEFT JOIN

3 个答案:

答案 0 :(得分:1)

在聊天和问题更新之后,这是解决方案的本质:

对于只有一列,您可以使用相关子查询:

SELECT
  prospect_evaluations.* 
  , (SELECT MAX(created_at) FROM prospect_evaluations_actions pea WHERE pea.evaluation_id = pe.id) AS last_action_at 
FROM
  `prospect_evaluations` pe

或者你可以加入一个子查询来计算每个evavluation_id的结果:

SELECT prospect_evaluations.*,
       prospect_evaluations_actions.evaluation_id,
       prospect_evaluations_actions.created_at AS last_action_at 
FROM `prospect_evaluations`
LEFT JOIN (select evaluation_id, max(created_at) as last_action_at from prospect_evaluations_actions group by evaluation_id) pea
  ON `pea`.`evaluation_id` = `prospect_evaluations`.`id`

为了检索整个记录,这有点棘手:

你必须做一个'自我加入'并将结果用作子查询:

SELECT 
 ...
FROM
  `prospect_evaluations` pe
  LEFT JOIN (
    SELECT pea.*
    (select evaluation_id, max(created_at) as last_action_at from prospect_evaluations_actions group by evaluation_id) pea_max
    INNER JOIN prospect_evaluations_actions pea
      on pea_max.evaluation_id = pea.evaluation_id and pea_max.last_action_at = pea.created_at
  ) pea_record
    ON pe.id = pea_record.evaluation_id

请注意,这仅适用于每个evaluation_id独有的created_at!

这些查询都没有经过测试,我可能有拼写错误。

答案 1 :(得分:0)

如果你只想要最后一个动作,你需要指定 - MAX是你的朋友。

DISTINCT过滤掉重复的行(其中每行有两行,每行都有相同的数据)。

聚合函数(min,max,avg,sum)允许您获取列并对其执行算术运算。如果您想要最后一个,那么您正在寻找具有最新created_at的行。

SELECT prospect_evaluations.*,
       prospect_evaluations_actions.evaluation_id,
       max(prospect_evaluations_actions.created_at) AS lastaction_created_at
FROM `prospect_evaluations`
LEFT JOIN `prospect_evaluations_actions` ON `prospect_evaluations_actions`.`evaluation_id` = `prospect_evaluations`.`id`
WHERE `prospect_evaluations`.`category` = 'to_contact'
  AND `archived_at` IS NULL
  AND `discarded_at` IS NULL
  AND `prospect_evaluations`.`hidden_at` IS NULL
ORDER BY IFNULL( CAST(prospect_evaluations_actions.created_at AS date), CAST(prospect_evaluations.created_at AS date) ) DESC, `prospect_evaluations`.`priority` DESC
group by prospect_evaluations.*,
       prospect_evaluations_actions.evaluation_id

答案 2 :(得分:0)

如果你想获得lastaction_created日期,你需要在日期上做一个MAX()。然后,您可以通过prospect_evaluations.id进行分组。

SELECT prospect_evaluations.*,
       prospect_evaluations_actions.evaluation_id,
       MAX(prospect_evaluations_actions.created_at) AS lastaction_created_at
FROM `prospect_evaluations`
LEFT JOIN `prospect_evaluations_actions` ON `prospect_evaluations_actions`.`evaluation_id` = `prospect_evaluations`.`id`
WHERE `prospect_evaluations`.`category` = 'to_contact'
  AND `archived_at` IS NULL
  AND `discarded_at` IS NULL
  AND `prospect_evaluations`.`hidden_at` IS NULL
GROUP BY prospect_evaluations.id
    ORDER BY IFNULL( CAST(prospect_evaluations_actions.created_at AS date), CAST(prospect_evaluations.created_at AS date) ) DESC, `prospect_evaluations`.`priority` DESC