【问题标题】:Select Query with MAX选择 MAX 查询
【发布时间】:2010-02-09 15:48:50
【问题描述】:

我遇到了一个大问题,我尝试了一整天,但没有找到任何解决方案。希望你能帮助我吗?

我有两张桌子:

第一个名为“orders”:

orders_id | orders_date | .....
1           xxxxxxxxxx
2           xxxxxxxxxx
3           xxxxxxxxxx

第二个是“orders_history”:

orders_id | order_status_id | date_added
1           1                 2009-10-01
1           2                 2010-01-01
2           1                 2010-02-01
3           1                 2010-02-01

所以现在我想要所有 order_status_id = '1' 的订单

我也尝试过使用 MAX、HAVING、GROUP BY、...子选择,但我还没有找到任何解决方案。我知道这并不难,但我已经完成了...... 是不是有点像:

SELECT orders.*, orders_history.* FROM orders, orders_history WHERE orders_history.order_status_id <= '1'

但是我也得到了 order_id 1 的订单

希望您能提供帮助。谢谢!

萨沙

为了进一步说明,发布者的“orders_history”表会随着时间的推移跟踪所有订单的状态。目标是查找所有当前订单状态为 1 的订单。订单 ID#1 当前的状态为 2,因此不应包含在结果中。

假设订单状态会随着时间的推移而上升,并且永远不会下降,因此订单状态和添加日期会不断增加。

【问题讨论】:

  • 如果您只想 order_status_id 为 1,请将其设为 '= 1',而不是 '
  • 一个问号还不够!?!?!?!?
  • 重复处理怎么样?
  • 对于如何确定订单处于什么状态存在一些困惑。它是基于 MAX(order_status_id) 还是 MAX(date_added)?
  • 我已编辑问题以添加我对问题的理解。 @codeworxx - 检查我是否正确。

标签: php select mysql


【解决方案1】:

这应该为你做:

SELECT * 
FROM orders
   , orders_history
WHERE orders.orders_id = orders_history.orders_id
AND orders.orders_id IN (
  SELECT orders_id 
    FROM orders_history
   GROUP BY orders_id
   HAVING MAX(order_status_id) = 1
)

【讨论】:

  • +1:这是一个更简单的我的。请注意,此查询忽略了 date_added,因此如果订单进入状态 1,然后进入状态 2,然后返回状态 1,则此查询将找不到它。但是 OP 在评论中暗示状态只能增加,所以这在实践中可能不是问题。
【解决方案2】:

我并不感到惊讶,您无法让它工作 - 这是一种非常棘手的查询类型,您必须“GROUP BY”并在同一行中找到 MAX 以及所有其他相应的值。这是一个常见的请求,并且经常让人们感到惊讶的是,实际上很难用 SQL 来表达这一点。这是在 MySQL 中执行此操作的一种方法:

SELECT T2.orders_id FROM (
    SELECT orders_id, MAX(date_added) AS date_added
    FROM orders_history
    GROUP BY orders_id
) AS T1
JOIN orders_history T2
ON T1.orders_id = T2.orders_id AND T1.date_added = T2.date_added
GROUP BY T2.orders_id, T2.date_added
HAVING MAX(order_status_id) = 1

这里我假设:

  • orders_id、date_added 不是唯一的。
  • orders_id、date_added、order_status_id 是唯一的。

如果不是第二个假设不成立,则在第一个 SELECT 之后添加 DISTINCT。

这是我从您的测试数据中得到的结果:

2
3

如果您想获取有关每个订单的额外信息,可以将其加入您的订单表。

【讨论】:

    【解决方案3】:

    在 cmets 中讨论后编辑(更改了 where 子句):

    SELECT orders.*, orders_history.* 
    FROM orders INNER JOIN orders_history
     ON orders.orders_id = orders_history.orders_id 
    WHERE orders.orders_id IN 
       (SELECT orders_id FROM orders_history 
       GROUP BY orders_id 
       HAVING MAX(order_status_id) = 1)
    

    【讨论】:

    • 不,他想仅使用 max(order_status_id) 关联表
    • @Scott Saunders - 我不确定你的意思。引用问题 - “所以现在我想要所有 order_status_id = '1' 的订单”。
    • OP 没有明确说明这一点。但这就是订单历史记录表的重点。订单经过各个阶段,他想找到当前处于阶段 1 的所有订单,而不是所有曾经处于阶段 1 的订单。这个问题可能不好提出,但我做过类似的事情,所以我想出了什么他正在尝试做。
    • i 只有 MAX(status_id) = 1 的订单!!!在我的示例中,id 为 2 和 3 的订单,而不是 id 1 的订单,因为它有 MAX(status_id) 2!!
    • 我相信有人给了你一个应该在此期间起作用的答案(即在我们澄清的时候:))。但只是另一个问题 - 考虑将 current_order_status 添加到 orders 表而不只是将其存储在 history 表中如何?
    【解决方案4】:
    select o.*, oh.* 
    from orders o
    inner join orders_history oh on oh.orders_id = o.orders_id
    where oh_orders_status = 1
    

    应该可以解决问题。虽然我接触 mysql 已经有一段时间了,所以我不知道你的 orders_status 是否应该用引号引起来 - 我猜它是否是 int...

    【讨论】:

    • 不,他只想使用 max(order_status_id) 关联表
    • 操作在哪里概述了这个要求?唯一提到的是他尝试使用 MAX,但他没有说明原因。从他提供的数据来看,假设你的假设是正确的,无论如何他只会为每条记录得到一个结果
    • 是的,但我只想要订单 WHERE order_status_id = '1' 意味着我只会得到 order_id = 2 和 3 作为结果,而不是 order_id = 1,因为有了那个 id,最大的状态是 2 而不是 1!
    • OP 没有明确说明这一点。但这就是订单历史记录表的重点。订单经过各个阶段,他想找到当前处于第 1 阶段的所有订单,而不是所有曾经处于第 1 阶段的订单。这个问题很糟糕(可怕),但我做过类似的事情,所以我想弄清楚他想做什么。
    • 哦,我明白了。请问他可以在问题中添加这个吗?或者有足够代表的人应该添加它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多