如何访问子查询中子查询内的字段?

时间:2014-09-07 05:47:46

标签: mysql correlated-subquery

以下是查询:

SELECT `o`.`price`,
       `us`.`avatar` AS `url`,
       `u`.`id`,
       `u`.`username`
FROM orders AS o
INNER JOIN `users` AS `u` ON `u`.`id` =
  (SELECT user_id
   FROM
     (SELECT s.vol,
             t_vol,
             user_id
      FROM orders s
      LEFT JOIN
        (SELECT Sum(vol) AS t_vol,
                order_id
         FROM order_transactions
         GROUP BY order_id) t ON s.id = t.order_id
      WHERE o.price = s.price HAVING vol - Ifnull(t_vol, 0) > 0) adsads
   ORDER BY s.vol DESC LIMIT 1)
INNER JOIN `user_settings` AS `us` ON `us`.`user_id` = `u`.`id`
WHERE `o`.`price` IN (10.00000000)
GROUP BY `o`.`price`

我知道它很重要,但问题很简单。 o.price(第5行到最后一行的WHERE o.price = s.price)无法访问,因为它位于嵌套子查询中。我真的不知道如何解决这个问题,为o.price制作别名无济于事。

编辑:我发现我需要一个相关的子查询。关于如何重构我的查询的任何想法都非常感谢。

编辑2:这里描述了我需要做的事情......

  • 计算每个订单的剩余量
  • 对于每个不同的价格,找到拥有最大剩余量的订单的用户的头像

剩余交易量:每个订单可以包含零个或多个order_transactions。订单的剩余量是该订单的原始量减去属于该订单的所有order_transactions的总和。


SQL FIDDLE:http://sqlfiddle.com/#!2/52a3d5

1 个答案:

答案 0 :(得分:0)

我实际上认为这是一个相当丑陋的查询但我在MySQL中没有看到任何其他方法:

SELECT prices.price, u.id, u.username, us.avatar AS url
FROM (
  SELECT mo.price, MIN(mo.user_id) u_id
  FROM (
    SELECT p.price, MAX(p.is_left) max_left
    FROM (
      SELECT o.price, o.vol - SUM(IFNULL(t.vol, 0)) is_left
      FROM orders o 
      LEFT JOIN order_transactions t on t.order_id = o.id
      GROUP BY o.price, o.vol, o.id
    ) p
    GROUP BY p.price
  ) m
  JOIN (
    SELECT o.id, o.user_id, o.price, o.vol - SUM(IFNULL(t.vol, 0)) is_left
    FROM orders o 
    LEFT JOIN order_transactions t on t.order_id = o.id
    GROUP BY o.id, o.user_id, o.price, o.vol
  ) mo ON mo.price = m.price AND mo.is_left = m.max_left
  GROUP BY mo.price
) prices
JOIN users u ON u.id = prices.u_id
JOIN user_settings us ON us.user_id = u.id

所以我收到所有订单,其中包含了剩余的交易,然后每个价格获得MAX()。然后我再次收到所有订单并JOIN按价格和is_left与刚刚确定的MAX(is_left)相同。这可能超过1个结果,因此我得到MIN(user_id)GROUP BY价格。然后加入此MIN(user_id),最终每个价格有1个用户。

这是我制作的 SqlFiddle ,我已经添加了一个不同价格的订单进行测试。