0

我必须为每个用户更新 n 个最旧的订单。现在我使用以下代码更新每个用户 1 条最旧的记录,但不知道如何更新 n 条记录......

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"

我找到了答案:

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";
4

2 回答 2

2

我认为这不会令人惊讶地执行,但是没有ROW_NUMBER()或其他 Window 函数,并且没有使用循环(甚至比这更糟糕),操作变得更加复杂:

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;

n这种情况下是3HAVING条款中。如果每个 User_ID 的数据量很少,这可以正常工作。如果每个查询都有数千行,那么查询很快就会变得相当缓慢和繁琐。

SQL Fiddle 示例

于 2012-06-07T11:08:41.573 回答
1

查看如何在查询中使用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)
于 2012-06-07T11:01:51.907 回答