加入VS SUBQUERY

时间:2014-03-10 23:05:24

标签: mysql join subquery correlated-subquery

我需要这样做但是使用子查询,而不是连接。我的问题是,如何使用子查询显示另一列?我可以从那里获取信息,但我将缺少orders表中的order_date列。我可以使用子查询来显示它吗?

SELECT CONCAT(c.customer_first_name, ' ' , c.customer_last_name) AS customer_name, MAX(o.order_date) AS recent_order_date
FROM customers AS c
JOIN orders AS o
ON c.customer_id = o.customer_id
GROUP BY customer_name
ORDER BY MAX(o.order_date) DESC

2 个答案:

答案 0 :(得分:1)

一点也不清楚你想要返回什么样的结果集,但它看起来像是无处不在的“最新行”问题。

解决该问题的规范模式是使用JOIN到内联视图。如果没有唯一约束,则可以返回多个匹配行。

要获取最新订单(orders表中每个客户的最大order_date行,假设(customer_id, order_date)元组是唯一的,您可以执行以下操作:

SELECT o.*
  FROM ( SELECT n.customer_id
              , MAX(n.order_date) AS latest_order_date
           FROM orders n
          GROUP BY n.customer_id
       ) m
  JOIN orders o
    ON o.customer_id = m.customer_id
   AND o.order_date = m.latest_order_date

如果您还想根据订单返回的customerscustomer_id表中检索列,您将使用JOIN(不是子查询)

SELECT CONCAT(c.customer_first_name,' ',c.customer_last_name) AS customer_name
     , c.whatever
     , o.order_date AS recent_order_date
     , o.whatever
  FROM ( SELECT n.customer_id
              , MAX(n.order_date) AS latest_order_date
           FROM orders n
          GROUP BY n.customer_id
       ) m
  JOIN orders o
    ON o.customer_id = m.customer_id
   AND o.order_date = m.latest_order_date
  JOIN customers c
    ON c.customer_id = o.customer_id
 ORDER BY o.order_date DESC, o.customer_id DESC

正如我之前提到的,如果给定客户可以拥有两个具有order_date完全相同值的订单,则每个customer_id可能会返回多个订单。

为了解决这个问题,我们可以从内联视图返回一个唯一键,并在连接谓词中使用它来保证只从订单返回一行。

(注意:这种方法特定于MySQL,使用这种语法,其他RDBMS会抛出一个错误,基本上说“GROUP BY必须包含所有非聚合”。但MySQL允许它。)

SELECT CONCAT(c.customer_first_name,' ',c.customer_last_name) AS customer_name
     , c.whatever
     , o.order_date AS recent_order_date
     , o.whatever
  FROM ( SELECT n.customer_id
              , MAX(n.order_date) AS latest_order_date
              , n.order_id
           FROM orders n
          GROUP BY n.customer_id
       ) m
  JOIN orders o
   AND o.customer_id = m.customer_id
   AND o.order_date = m.latest_order_date
   AND o.order_id = n.order_id
  JOIN customers c
    ON c.customer_id = o.customer_id
 ORDER BY o.order_date DESC, o.customer_id DESC

答案 1 :(得分:0)

我不确定我理解你的问题,但我认为这有效......(虽未测试......)

SELECT
  (
    SELECT
      CONCAT(c.customer_first_name, ' ' , c.customer_last_name) 
    FROM
      customers c 
    WHERE
      c.customer_id = o.customer_id 
    LIMIT 1
  ) AS customer_name,
  MAX(o.order_date) AS recent_order_date
FROM
  orders o 
GROUP BY 
  customer_name
ORDER BY 
  MAX(o.order_date) DESC