【问题标题】:Conditional Where clause if Left Join returns rows?如果左连接返回行,则条件 Where 子句?
【发布时间】:2012-05-01 12:47:59
【问题描述】:

我觉得有一种方法可以使用条件 Cases 或 Ifs 来做到这一点,但我就是想不通。

下面的查询将三个表连接在一起,如果所有三个表都返回行,则效果很好。但是,在某些情况下,campaign_groups 和 new_advertisers 中存在记录,但 payment_transactions 中没有。

由于 WHERE 子句确保 payment_transactions.transaction_date >=campaign_groups.date_created,零交易的行被排除在外。

有没有办法只在 LEFT JOIN 返回行时应用 WHERE 子句?

SELECT sum(payment_transactions.transaction_amount) as payment, 
            new_advertisers.account_id, 
            new_advertisers.advertiser_id,
            max(payment_transactions.transaction_date) as last_payment,
            campaign_groups.id,
            campaign_groups.date_created,
            TIMESTAMPDIFF(DAY, max(payment_transactions.transaction_date), NOW()) as days_passed
        FROM campaign_groups
        INNER JOIN new_advertisers ON campaign_groups.advertiser_id = new_advertisers.advertiser_id
        LEFT JOIN payment_transactions ON payment_transactions.account_id = new_advertisers.account_id
        WHERE payment_transactions.transaction_date >= campaign_groups.date_created
            AND campaign_groups.weekly_budget_cents > 0
        ORDER BY days_passed DESC

【问题讨论】:

    标签: mysql left-join where-clause conditional-statements


    【解决方案1】:

    将条件移到您的 ON 子句中:

    LEFT JOIN payment_transactions
        ON payment_transactions.account_id = new_advertisers.account_id
        AND payment_transactions.transaction_date >= campaign_groups.date_created
    WHERE campaign_groups.weekly_budget_cents > 0
    

    【讨论】:

    • 所以这行得通。如果我删除 SELECT 中的聚合函数(例如 SUM、MAX),它会起作用,大概是因为如果这些字段不存在则无法聚合?我尝试添加一个 IFNULL 来检查,但这没有帮助。例如。 IFNULL(SUM(payment_transactions.transaction_amount),0) 作为付款,
    • @Zach:您的查询看起来不对。您是否缺少 GROUP BY?使用聚合函数时,将不在聚合函数或 GROUP BY 子句中的字段包含在 SELECT 列表中通常是错误的。事实上,大多数其他数据库会立即给您一个错误,甚至不会尝试运行该查询。您可以将 MySQL 配置为更严格,这样它也会为您的查询提供错误,而不是返回无用的结果。请参阅此处了解更多信息:dev.mysql.com/doc/refman/5.6/en/group-by-hidden-columns.html
    • 啊,成功了。我需要对 new_advertisers.account_id 进行额外的 GROUP BY,并在 days_passed 上进行 IFNULL() 测试(因为如果没有返回交易,它将为空)。感谢您的帮助!
    猜你喜欢
    • 2013-07-28
    • 1970-01-01
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    相关资源
    最近更新 更多