2012-06-07 4 views
0

각 사용자별로 가장 오래된 주문을 업데이트해야합니다. 방법을 알아각 사용자에 대해 n 개의 레코드를 업데이트하십시오.

set @num := 0, @type := ""; 

UPDATE orders INNER JOIN(

SELECT id, user_id, created, row_number FROM (
    SELECT id, user_id, created, 
     @num := if(@type = user_id, @num + 1, 1) AS row_number, 
     @type := user_id AS dummy 
    FROM orders 
    WHERE status = "queue" 
    ORDER BY user_id, created asc) AS grouped_orders 
WHERE grouped_orders.row_number <= 2 

) m ON orders.id = m.id SET orders.status = "process", orders.lock_id = "somehash"; 

답변

1

확인 : 지금은 코드를 다음 사용하기위한

UPDATE orders 
       INNER JOIN (
        SELECT id, MIN(created) AS created 
        FROM orders 
        WHERE status="queue" AND type="order" 
        GROUP BY user_id 
       ) m ON orders.id = m.id 
      SET orders.status = "process", 
       orders.lock_id ="somehash" 

내가 anserw 발견 ... 사용자 당 1 개 오래된 레코드를 업데이트 할 수 있지만, n 개의 레코드를 업데이트하는 방법을 알아낼 수 없습니다 귀하의 질의에 limitorder by을 사용하십시오. 이것들은 각 사용자에 대해 n 개의 가장 오래된 레코드를 얻을 수 있도록 도와줍니다.

그런 다음 각 항목에 대해했던 것처럼 업데이트해야합니다.

당신이 유사한 쿼리를 사용해야 할 수도 있습니다 :

update table set WHAT_YOU_WANT_TO_SET 
where table.id in (select id, etc from other_table USING_LIMIT_AND_ORDER_BY) 
+0

제한을 늘 여기에 도움 – user606521

2

나는이 놀라 울 수행 할 것이라고 생각하지 않는다, 그러나 ROW_NUMBER() 또는 다른 윈도우 함수없이 (이보다 더 나쁜) 루프를 사용하지 않고 동작은 더 복잡해지고 :

UPDATE Orders 
     INNER JOIN 
     ( SELECT o1.ID 
      FROM Orders o1 
        LEFT JOIN Orders o2 
         ON o2.User_ID = o1.User_ID 
         AND o2.CreatedDate < o1.CreatedDate 
      GROUP BY o1.ID 
      HAVING COUNT(*) < 3 
     ) o 
      ON orders.ID = o.ID 
SET  Status = 1; 

이 경우 nHAVING 절의 3이다. User_ID 당 적은 양의 데이터가 있으면이 작동합니다. 각 쿼리에 대해 수천 개의 행이있는 경우 곧 매우 느리고 성가 시게됩니다.

Example on SQL Fiddle

관련 문제