2014-09-07 6 views
1

다음은 쿼리 :하위 쿼리 내의 하위 쿼리 내부 필드에 어떻게 액세스합니까?

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 : 여기에 내가 무엇을해야하는지에 대한 설명은 ...

  • 계산 각각 별개의 가격에 매 위해
  • 나머지 볼륨, 사용자의 아바타를 찾을 수있는 각 순서는 제로를 가질 수 나 : 가장 큰 나머지 볼륨

남은 볼륨 순서를 소유 more order_transactions. 주.의 나머지 볼륨은 해당 주.의 원래 볼륨에서 해당 주.에 속한 모든 order_transactions의 합계를 뺀 값입니다.


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

+0

이 쿼리는 확실히 리팩터링 될 수 있다고 확신합니다. 하나의 MySQL은'join'을 서브 쿼리보다 최적화하는 것이 더 좋으므로 가능한 경우 서브 쿼리를 사용하고 싶습니다. 테이블 구조를 제공하고 어떤 사용자를 선택하려고하는지 일반 영어로 설명 할 수 있습니까? 가장 큰 주문량을 가진 사용자와 비슷하지만 쿼리만으로는 명확하지 않습니다. – funkwurm

+0

각 가격대에서 주문 수량이 가장 많은 사용자입니다. 주.의 나머지 볼륨은 해당 주.과 관련된 주. 트랜잭션의 합계를 해당 주.의 원래 볼륨에서 + 어서 계산됩니다. (orders 테이블의 볼륨은 절대로 변경되지 않습니다.) 즉. o.vol - SUM (ot.vol) – kryo

+0

[SqlFiddle] (http://sqlfiddle.com/)을 사용하여 데이터 구조의 (단순화 된) 버전을 만들 수 있습니까? – funkwurm

답변

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는 just-determined MAX(is_left)과 동일합니다. 이것은 1 개 이상의 결과 일 수 있으므로 MIN(user_id)GROUP BY 가격이 나옵니다. 그런 다음 MIN(user_id)에 가입하여 가격 당 1 명의 사용자를 확보하십시오.

여기는 SqlFiddle입니다. 테스트를 위해 다른 가격으로 주문을 추가했습니다.