【问题标题】:Selecting most recently added row选择最近添加的行
【发布时间】:2013-01-15 11:58:18
【问题描述】:

我有 3 个具有以下架构的实体(订单、项目和订单项目):

                    OrderItems
    Orders      +---------------+
+-----------+   | id (PK)       |     Items
| id (PK)   |==<| order_id (FK) |   +-------+
| createdAt |   | item_id (FK)  |>==| id    |
+-----------+   | createdAt     |   | name  |
                | quantity      |   +-------+
                +---------------+

我需要保留 OrderItems 的历史记录,这样如果 OrderItem 的数量发生变化,我们就会记录每次后续变化的原始数量。

我的问题是,我希望能够为每个订单仅从表格中选择最新的商品。例如:

First two (initial) OrderItems:
    (id: 1, order_id: 1, item_id: 1, createdAt: 2013-01-12, quantity: 10),
    (id: 2, order_id: 1, item_id: 2, createdAt: 2013-01-12, quantity: 10),

Later order items are amended to have different quantities, creating a new row:
    (id: 3, order_id: 1, item_id: 1, createdAt: 2013-01-14, quantity: 5),
    (id: 4, order_id: 1, item_id: 2, createdAt: 2013-01-14, quantity: 15),

我在查询中尝试这样做:

SELECT oi.* FROM OrderItems oi
WHERE oi.order_id = 1
GROUP BY oi.item_id
ORDER BY oi.createdAt DESC;

我希望会产生这个:

| id | order_id | item_id | createdAt  | quantity |
+----+----------+---------+------------+----------+
| 3  | 1        | 1       | 2013-01-14 | 5        |
| 4  | 2        | 2       | 2013-01-14 | 15       |

其实是这样制作的:

| id | order_id | item_id | createdAt  | quantity |
+----+----------+---------+------------+----------+
| 1  | 1        | 1       | 2013-01-12 | 10       |
| 2  | 2        | 2       | 2013-01-12 | 10       |

目前我认为仅使用 createdAt 时间戳就足以识别项目的历史记录,但是我可能会转向从每个订单项目(链表)链接到前一个项目。如果这样可以更轻松地进行此查询,我将继续进行。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    试试这个:

    SELECT 
      oi.*
    FROM OrderItems oi
    INNER JOIN
    (
       SELECT item_id, MAX(createdAt) MaxDate
       FROM OrderItems
       WHERE order_id = 1
       GROUP BY item_id
    ) o2  ON oi.item_id = o2.item_id
         AND DATE(oi.CreatedAt) = DATE(o2.MaxDate)
    ORDER BY oi.createdAt DESC;
    

    SQL Fiddle Demo

    这会给你:

    | ID | ORDER_ID | ITEM_ID |  CREATEDAT | QUANTITY |
    ---------------------------------------------------
    |  3 |        1 |       1 | 2013-01-14 |        5 |
    |  4 |        1 |       2 | 2013-01-14 |       15 |
    

    【讨论】:

    • 嗨,马哈茂德,谢谢,这真的很有帮助。我稍作修改以使用 MAX(createdAt) (以降序排列日期)。再次感谢!
    • @Ross - 抱歉。刚看到。现已修复。
    【解决方案2】:

    这是另一个解决方案:绝对不反对 Mahmoud :D(感谢 sqlfiddle) 如果你想试试。

    查询:

    SELECT * FROM orderitems
    GROUP BY id
    ORDER BY createdAt DESC
    LIMIT 2
    ;
    

    结果:

    | ID | ORDER_ID | ITEM_ID |                      CREATEDAT | QUANTITY |
    -----------------------------------------------------------------------
    |  3 |        1 |       1 | January, 14 2013 02:00:00+0000 |        5 |
    |  4 |        1 |       2 | January, 14 2013 02:00:00+0000 |       15 |
    

    【讨论】:

    • @Ross 我知道你已经接受了一个很好的答案:) 这是另一种方法。如果您有兴趣尝试一下。
    • 谢谢,这需要您先知道有多少订单商品。
    • @Ross 好吧,这不是必需的,但是如果您在 Item_ID 1 中的日期晚于 item_id 2,那么这将不起作用。除此之外它还有效。
    猜你喜欢
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多