【问题标题】:Select data from specific row of grouped and joined table in MySQL从 MySQL 中分组和连接表的特定行中选择数据
【发布时间】:2020-05-30 18:41:31
【问题描述】:

我有两个表,客户和订单,它们是内部连接的。一个客户可以有多个与其关联的订单。在我的选择中,我然后按customers.id 分组。我需要选择每个客户最近的订单,还要选择在该订单上花费的金额。目前,我可以选择最近的order_date,但不知道如何选择与order_date在同一行的金额。

这是我当前的查询:

SELECT 
    first_name, 
    last_name, 
    email, 
    MAX(order_date) AS recent_order, 
    amount -- this needs to select amount associated with recent_order
FROM customers
JOIN orders
    ON customers.id = orders.customer_id
GROUP BY customers.id;

查询选择最近的日期,但不选择与最近的order_date关联的金额。

表声明:

CREATE TABLE customers (
    id INT AUTO_INCREMENT PRIMARY KEY,
    first_name VARCHAR(100),
    last_name VARCHAR(100),
    email VARCHAR(100)
);

CREATE TABLE orders (
    id INT AUTO_INCREMENT PRIMARY KEY,
    order_date DATE,
    amount DECIMAL(8,2),
    customer_id INT,
    FOREIGN KEY(customer_id) REFERENCES customers(id)
);

【问题讨论】:

    标签: mysql sql group-by


    【解决方案1】:

    我建议在where 子句中使用相关子查询:

    SELECT c.*, o.*  -- or whatever columns you want
    FROM customers c JOIN
         orders o
         ON c.id = o.customer_id
    WHERE o.order_date = (SELECT max(o2.order_date)
                          FROM orders o2
                          WHERE o2.customer_id = o.customer_id
                         );
    

    为了提高性能,您需要在orders(customer_id, order_date) 上建立索引。

    【讨论】:

    • 为什么推荐这个?
    • 谢谢你,这行得通!但是,有没有办法使用 group by 来做到这一点,因为据我了解,使用子查询会降低性能
    • @Cirrus86 。 . .实际上,group by 通常会变慢。添加推荐的索引,您可能无法获得更快的查询。
    • @RMac。 . .因为这应该在包括 MySQL 在内的大多数数据库中具有最快的性能。
    【解决方案2】:

    使用这个:

    SELECT TOP 1
        t1.first_name, 
        t1.last_name, 
        t1.email, 
        t2.order_date,
        t2.amount
    FROM customers t1
    JOIN orders t2
        ON t1.id = t2.customer_id
    ORDER BY
        t2.order_date
    

    如果意图返回所有具有最近 order_date 的行,请添加 GROUP BY t1.id。如果每个订单都被orders 中的一行重新发送,请忽略此选项。请注意,这不会合计金额。您必须在代码中执行此操作,否则使用不同的查询。另请注意,此查询的性能将受索引配置的影响。如果 order_date 不是索引的一部分并且表包含大型数据集,则此查询可能无法执行。

    【讨论】:

    • 问题是 GROUP BY 子句不能出现在 ORDER BY 之后,至少在 MySQL 中是这样。将 GROUP BY 放在 ORDER BY 之前只会对组进行排序
    • 这就是为什么您保留查询的 TOP 1 和 ORDER BY 部分...
    【解决方案3】:
    SELECT 
        first_name, 
        last_name, 
        email, 
        MAX(order_date) AS recent_order, 
        (SELECT amount FROM orders WHERE order_date = MAX(order_date) AND customers.id = orders.customer_id) as amount
    FROM customers
    JOIN orders
        ON customers.id = orders.customer_id
    GROUP BY customers.id;
    

    SELECT 
        first_name, 
        last_name, 
        email, 
        order_date AS recent_order, 
        amount AS recent_order_amount
    FROM customers
    JOIN orders
        ON customers.id = orders.customer_id
    
    GROUP BY customers.id
    ORDER BY orders.order_date DESC;
    

    【讨论】:

    • 第一个选项抛出“错误 1111 (HY000): 无效使用组函数”。第二个选项抛出 'ERROR 1064 (42000): You have an error in your SQL syntax;检查与您的 MySQL 服务器版本相对应的手册,以在第 21 行的“GROUP BY customers.id”附近使用正确的语法。有没有办法解决这个问题?
    • 第二个现在应该可以工作了。一开始的问题是使用 MAX 和 GROUP BY
    • 在 group by 之后使用 order by 只是对分组的行进行排序,而不是对组内的值进行排序
    猜你喜欢
    • 1970-01-01
    • 2021-07-09
    • 2012-05-14
    • 2011-05-17
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多