2017-02-01 13 views
0

私がやっていることは、MySQLがテーブルの主キーによって重複した行を選択するのを防ぐことです。LEFT JOINを使用したMySQL DISTINCTクエリは、プライマリキーで複製された行を選択します。

データは実際のものではなく、質問のためのものです。

prospect_evaluations 
id | category | archived_at | discarded_at | hidden_at 
1 | to_contact |  null |   null |  null 
2 | to_contact |  null |   null |  null 
3 | to_convert |  null |   null |  null 
4 | to_convert |  null |   null |  null 

prospect_evaluations_actions 
id | evaluation_id | created_at 
1 |    1 | 01-02-2017 01:00:00 
2 |    1 | 01-02-2017 02:00:00 
3 |    2 | 01-02-2017 03:00:00 
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 

EDIT:評価は歴史の中で4つのアクションがあった場合、それはつもり4回複製されているように私は、彼らが評価にリンクされているどのように多くのアクションに応じて、結果が重複していることに気付きました。私は創造日を選択してそれを使って自分のエントリーを注文できるように、最後のアクションだけが必要です!表2のジョインTABLE1の

  • SELECT
  • LEFT:

    EDIT 2:この質問は、で構成されているため、このような状況、可能性の重複としてフラグ付けされたものと比較しては、異なっています。

重複質問ではなく、から構成されています。TABLE1の

  • SELECT
  • LEFTは、あなただけの最後のアクションをしたい場合は、あなたがそう指定する必要がTABLE1
+1

クエリと結果セットの列数が同じではありません。あなたは列がありません。 FYI DISTINCTは個々の列または主キーではなく、行レベルで作業しています。 – Pred

+0

@Pred結果セットを固定してより理にかなっているようにしました。代わりにCOLUMNレベルで動作させるにはどうすればよいですか?または、LEFT JOINの結果を1に制限するにはどうすれば問題が発生するのですか? – GiamPy

+0

今は複製されていますか? – Pred

答えて

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 

それとも:

1列のみのために、あなたは、相関サブクエリを使用することができます各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 

、この意志だけで動作することcreated_atがevaluation_idごとに一意のとき!

これらのクエリはテストされていません。タイプミスがある可能性があります。

0

の結合 - MAXをあなたの友だちです。

DISTINCTは、重複する行(すべての列に同じデータを持つ2つの行がある)を除外します。

集計関数(最小、最大、平均、合計)を使用すると、列を取得して算術演算を実行できます。最後のものが必要な場合は、最新の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 
+0

私はそれを何回も試みましたが、構文エラーがあるようです。ああ、そしてGROUP BYはORDER BYの前に行く! – GiamPy

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 
+0

"ORDER BY句の式#1はGROUP BY句にはなく、GROUP BY句のカラムに機能的に依存しない非集約カラム 'devdb_core.prospect_evaluations_actions.created_at'を含んでいます。 – GiamPy

関連する問題