【问题标题】:Trouble using MAX() with a table JOIN将 MAX() 与表 JOIN 一起使用时遇到问题
【发布时间】:2014-07-10 12:49:03
【问题描述】:

这是我正在尝试转换的当前查询,它需要一个项目 ID,然后接收具有最新日期和类型不等于 TRAN 的相应价格/数量/供应商 ID。

 SELECT  cs_po_products.price, cs_po_products.qty, cs_po.vendor_id 
        FROM cs_po_products, cs_po
        WHERE cs_po_products.stock_number = :items_id
        AND cs_po_products.po_number = cs_po.id 
        AND type !='TRAN'
        ORDER BY cs_po.date_ordered DESC
        LIMIT 1

这个查询工作正常,但是它必须执行很多次,这使得加载页面有点慢。我正在尝试创建一个查询,该查询将为每个 stock_number 获取最新 date_ordered 的 ROW。在寻找答案时,我遇到了很多技术,但最常见的是两个表的 JOIN,其中 MAX() 为 date_ordered。但唉,我似乎无法提出正确的查询。

这是众多尝试之一,但我认为是最接近的。

SELECT a.price, a.qty, b.vendor_id, a.stock_number, b.max, b.type
 FROM cs_po_products a
 LEFT JOIN (SELECT MAX(date_ordered)as max,vendor_id,type, date_ordered,id FROM cs_po) b 
 ON b.id = a.po_number 
 WHERE stock_number != '' AND date_ordered IS NOT NULL 
 AND type !='TRAN'
 ORDER BY stock_number, date_ordered DESC

如果有人能指出我正确的方向,在此先感谢

编辑:

所有提供的答案仍然给出不止一行的股票编号,例如:

 price      qty     vendor_id   stock_number    date_ordered
 0.05446    123750  51          00010005.01S    2014-02-24 15:29:00
 0.05446    123750  51          00010005.01S    2014-01-02 14:25:00
 0.05446    123750  51          00010005.01S    2013-11-04 13:48:00
 0.05402    123750  51          00010005.01S    2013-08-20 10:02:00
 0.0532     123750  51          00010005.01S    2013-07-12 09:21:00
 0.0538     123750  51          00010005.01S    2013-04-02 12:15:00
 0.0532     123750  51          00010005.01S    2012-12-27 00:00:00
 0.0555     101750  51          00010005.01S    2012-11-07 10:55:00
 0.555      137500  51          00010005.01S    2012-11-02 09:39:00
 0.0532     137500  51          00010005.01S    2012-11-02 09:37:00
 0.0532     123750  51          00010005.01S    2012-10-03 00:00:00

我想要在这个结果中唯一的行是第一行,因为它有最近的日期,但在实际结果中有更多的 stock_numbers 低于我想要那些相应的最大日期

【问题讨论】:

标签: mysql


【解决方案1】:

从 cs_po 获取每个 id 的最新 date_ordered 的子查询,然后将其与 cs_po 连接以从表中获取其他值:-

SELECT  cs_po_products.price, cs_po_products.qty, cs_po.vendor_id 
FROM cs_po_products
INNER JOIN 
(
    SELECT id, MAX(date_ordered) AS date_ordered
    FROM cs_po
    GROUP BY id
) sub0
ON cs_po_products.po_number = sub0.id 
INNER JOIN cs_po
ON sub0.id  = cs_po.id 
AND sub0.date_ordered = cs_po.date_ordered
WHERE type !='TRAN'

编辑。

最好猜测你想要得到什么。但如果没有表格布局和输入测试数据,这在很大程度上是一种猜测。

SELECT a.*, b.*
FROM
(
    SELECT a.stock_number, MAX(date_ordered) AS date_ordered
    FROM cs_po_products a
    INNER JOIN cs_po b 
    ON b.id = a.po_number
    GROUP BY a.stock_number
) sub0
INNER JOIN cs_po_products a
ON a.stock_number = sub0.stock_number
INNER JOIN cs_po b 
ON b.id = a.po_number
AND b.date_ordered = sub0.date_ordered
WHERE type !='TRAN'

【讨论】:

  • 如此接近,但这也会为单个 stock_number 获取多行
  • 这应该为每个 po_number 提供一条记录。您可以发布一些示例输入数据供我们处理吗?否则很难想出一个解决方案。例如,cs_po_products 表中的库存编号是否有多个记录?
  • 抱歉等待,此查询不应为每个 po_number 提供一条记录,这只是 id 的 db 键。此查询应为每个 stock_number 提供一条记录,其中返回的记录是最近 date_ordered 的行。表中有多个股票# 的记录,如果你看上面我做了一个编辑。
  • 又一次尝试,但确实需要表格布局和输入数据才能有很大的机会提出解决方案。
  • 是的,先生,您的第二次编辑确实获得了每个 stock_number 的最近日期的行。感谢您的所有帮助 - 正确的查询是您的编辑,我最终将 * 更改为仅需要的正确字段
【解决方案2】:

试试这个方法:

 SELECT a.price, a.qty, b.vendor_id, a.stock_number, b.max, b.type
   FROM cs_po_products a
         LEFT JOIN (SELECT vendor_id, type, date_ordered, id, 
                           MAX(date_ordered)as max 
                      FROM cs_po
                     GROUP BY date_ordered) b 
             ON a.po_number = b.id
  WHERE a.stock_number != '' 
    AND b.date_ordered IS NOT NULL 
    AND b.type !='TRAN'
  ORDER BY a.stock_number, b.date_ordered DESC

【讨论】:

  • 这很接近,但问题是每个 stock_number 都有多行与相应的日期,只是按 DESC 顺序排列。所以它不仅得到每个 stock_number 的 MAX 日期的行
【解决方案3】:

在第一个查询中,只需删除限制和 where 条件并按 cs_po_products.stock_number 和相同的 order by 添加组,以便它只选择第一次出现。我希望这应该有效。

希望这些链接可以帮助您
SQL Select only rows with Max Value on a Column
How to select single row based on the max value in multiple rows

【讨论】:

    【解决方案4】:

    避免使用反连接的子查询:

    SELECT cpp.price, cpp.qty, cp1.vendor_id, cpp.stock_number, cp1.date_ordered 
    FROM cs_po_products cpp
    JOIN cs_po cp1
      ON cp1.id = cpp.po_number
      AND cp1.date_ordered IS NOT NULL
      AND cp1.type != 'TRAN'
    LEFT JOIN cs_po cp2
      ON cp2.id = cpp.po_number
      AND cp2.type != 'TRAN'
      AND cp2.date_ordered > cp1.date_ordered
    WHERE cpp.stock_number != ''
      AND cp2.id IS NULL
    ORDER BY cpp.stock_number ASC
    

    这将为具有多个具有相同最近日期的 co_po 记录的 cs_po_products 记录返回多行,因为您没有指定在这种情况下使用哪条记录。

    您的某些列对它们属于哪个表不明确,所以如果我弄错了,请告诉我。

    【讨论】:

    • 我把它改成了这个查询SELECT cpp.price, cpp.qty, cp1.vendor_id, cpp.stock_number, cp1.date_ordered FROM cs_po_products cpp JOIN cs_po cp1 ON cp1.id = cpp.po_number AND cp1.date_ordered IS NOT NULL LEFT JOIN cs_po cp2 ON cp2.id = cpp.po_number AND cp2.date_ordered > cp1.date_ordered WHERE cpp.stock_number != '' AND cp1.type !='TRAN' ORDER BY cpp.stock_number ASC, cp1.date_ordered DESC 并且每个stock_number 有多个结果
    • @Darwin - 您从 WHERE 子句中省略了 AND cp2.id IS NULL,这对于此方法的工作至关重要(它正在检查正在处理的 cs_po 记录是否是最新的记录)。
    • @Darwin,我用type 属于cs_po 的信息更新了查询。没有理由对 cp1.date_ordered 进行二次排序,因为每个 cs_po_products 记录只有一个日期。
    • 对不起,我不知道我是如何没有将 IS NULL 复制到该评论中的。当我尝试它时,我实际上并没有将它从查询中删除。但是,此查询仍然会为单个 stock_number 提供多个结果。
    • @Darwin,正如我在帖子中提到的那样,如果存在具有相同最大日期的重复项,则会出现这种情况。如果还有其他问题,请说明。如果您可以决定应显示哪些具有相同日期的记录,请提供标准。我们总是可以使用GROUP BY 返回一个不确定的行。
    猜你喜欢
    • 1970-01-01
    • 2013-03-20
    • 2021-07-15
    • 2013-06-19
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多