【问题标题】:SQL get MAX datetime in LEFT JOINSQL 在 LEFT JOIN 中获取 MAX 日期时间
【发布时间】:2020-10-12 20:09:10
【问题描述】:

我正在对表运行查询并进行左连接以尝试从左表中获取最新日期的记录,但它没有获取与日期时间列相关的其他值(用户和注释)

SELECT
    i.customer_sequence,
    i.due_date,
    
    MAX(cn.datetime) as notes_datetime,
    cn.user as notes_user,
    cn.notes as notes_notes
FROM
    billing_invoices i
LEFT JOIN customer_notes cn
    ON i.customer_sequence = cn.customer_seq
WHERE
    cn.type = 'Accounts' AND
    i.customer_sequence <> '0' AND
    i.status = 'Unpaid' AND
    i.directdebit <> 'Y'
GROUP BY
    i.customer_sequence
ORDER BY
    i.due_date DESC

【问题讨论】:

    标签: mysql sql join greatest-n-per-group window-functions


    【解决方案1】:

    聚合不是这里的解决方案。您想要连接表中的整行,因此建议进行过滤。如果您运行的是 MySQL 8.0,我会推荐窗口函数:

    SELECT *
    FROM (
        SELECT
            i.customer_sequence,
            i.due_date,
            ROW_NUMBER() OVER(PARTITION BY i.customer_sequence ORDER BY cn.datetime DESC) rn,
            cn.datetime as notes_datetime,
            cn.user as notes_user,
            cn.notes as notes_notes
        FROM billing_invoices i
        LEFT JOIN customer_notes cn
            ON  i.customer_sequence = cn.customer_seq
            AND cn.type = 'Accounts'
        WHERE
            i.customer_sequence <> '0' AND
            i.status = 'Unpaid' AND
            i.directdebit <> 'Y'
    ) t
    ORDER BY i.due_date DESC    
    

    请注意,我将left joined 表上的条件从WHERE 子句移至连接的ON 子句(否则,这就像inner join)。


    在早期版本中,一个选项是相关子查询:

    SELECT
        i.customer_sequence,
        i.due_date,
        cn.datetime as notes_datetime,
        cn.user as notes_user,
        cn.notes as notes_notes
    FROM billing_invoices i
    LEFT JOIN customer_notes cn
        ON  i.customer_sequence = cn.customer_seq
        AND cn.type = 'Accounts'
        AND cn.datetime = (
            SELECT MAX(cn1.datetime)
            FROM customer_notes cn1
            WHERE i.customer_sequence = cn1.customer_seq AND cn1.type = 'Accounts'
        )
    WHERE
        i.customer_sequence <> '0' AND
        i.status = 'Unpaid' AND
        i.directdebit <> 'Y'
    

    【讨论】:

    • 返回错误#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(PARTITION BY i.customer_sequence ORDER BY cn.datetime DESC) rn, cn.dat' at line 6
    • 刚刚尝试了更新,从20 errors were found during analysis.开始出现更大的错误
    • @charlie:我想您的 MariaDB 版本不支持窗口函数(它们是在 10.3 中添加的)。我用没有窗口功能的解决方案更新了我的答案。
    • 好吧,虽然似乎已经减慢了查询速度。有没有办法加快速度,或者循环billing_invoices 表并在每个循环中查询customer_notes 会更快吗?
    • @charlie:您可以尝试利用customer_notes(customer_seq, type, datetime) 上的索引。您还可以升级到最新版本的 MariaDB 并使用窗口函数解决方案。
    猜你喜欢
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-28
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    相关资源
    最近更新 更多