我的数据库里有存货数量信息。
1个表“stock”包含productid(sku)以及数量和文件名。
另一个表“stockfile”包含所有处理过的文件名和日期。
现在我需要得到所有产品的最新库存价值。
这给了我所有的产品与所有的库存数量多次(导致300000记录)
选择stock.stockid、stock.sku、stock.quantity、stockfile.filename、stockfile.date
现货
stock.stockfileid=stockfile.stockfileid上的内部联接stockfile
stockskuASC排序
我已经试过了:
从库存中选择*
stock.stockfileid=stockfile.stockfileid上的内部联接stockfile
按sku分组
拥有stockfile.date=MAX(stockfile.date)
stockskuASC排序
但没用
显示创建表库存:
创建表stock(
stockidbigint(20)非空自动递增,
sku字符(25)不为空,
quantityint(5)不为空,
creationdate日期时间不为空,
stockfileidsmallint(5)unsigned不为空,
touchdate日期时间不为空,
主键(stockid
)引擎=MyISAM AUTO_INCREMENT=315169默认字符集=latin1
显示创建表stockfile:
创建表stockfile(
stockfileidsmallint(5)unsigned NOT NULL自动递增,
filenamevarchar(25)不为空,
creationdate日期时间默认值为空,
touchdate日期时间默认值为空,
date日期时间默认值为空,
begindate日期时间默认值为空,
enddate日期时间默认值为空,
主键(stockfileid
)引擎=MyISAM AUTO_INCREMENT=265默认字符集=latin1

最佳答案

这是我们每周在StackOverflow上看到的一个常见的“greatest-n-per-group”问题的例子。按照标签查看其他类似的解决方案。

SELECT s.*, f1.*
FROM stock s
INNER JOIN stockfile f1
  ON (s.stockfileid = f1.stockfileid)
LEFT OUTER JOIN stockfile f2
  ON (s.stockfileid = f2.stockfileid AND f1.date < f2.date)
WHERE f2.stockfileid IS NULL;

如果stockfile中有多行具有最大日期,您将在结果集中获得这两行。要解决这个问题,您必须在f2上的join中添加一些tie breaker条件。
感谢您添加CREATE TABLE信息。当你问SQL问题时,这非常有用。
我从AUTO_INCREMENT表选项中看到,stock中有315k行,stockfile中只有265行。stockfile表是关系中的父表,stock表是子表,列stockfileid引用stockfile的主键。
所以你最初的问题是误导。您需要stock中的最新行,而不是stockfile中的最新行。
SELECT f.*, s1.*
FROM stockfile f
INNER JOIN stock s1
  ON (f.stockfileid = s1.stockfileid)
LEFT OUTER JOIN stock s2
  ON (f.stockfileid = s2.stockfileid AND (s1.touchdate < s2.touchdate
      OR s1.touchdate = s2.touchdate AND s1.stockid < s2.stockid))
WHERE s2.stockid IS NULL;

我假设您希望“latest”是相对于touchdate的,所以如果您想改用creationdate,可以进行编辑。
我在连接中添加了一个术语,以便解决连接问题。我知道你说过日期“几乎是独一无二的”,但俗话说,“one in a million is next Tuesday
好吧,我想我明白你现在想做什么了。您需要每个sku的最新行,但是用来比较它们的date在引用表stockfile中。
SELECT s1.*, f1.*
FROM stock s1
JOIN stockfile f1 ON (s1.stockfileid = f1.stockfileid)
LEFT OUTER JOIN (stock s2 JOIN stockfile f2 ON (s2.stockfileid = f2.stockfileid))
  ON (s1.sku = s2.sku AND (f1.date < f2.date OR f1.date = f2.date AND f1.stockfileid < f2.stockfileid))
WHERE s2.sku IS NULL;

这会自动将stock连接到自身,查找具有相同sku和较新date的行。如果未找到,则s1包含其sku的最新行。每个stock实例都必须连接到其stockfile才能得到date
重新评论优化:我很难测试,因为我没有填充与您的数据匹配的表,但我想您应该有以下索引:
CREATE INDEX stock_sku ON stock(sku);
CREATE INDEX stock_stockfileid ON stock(stockfileid);
CREATE INDEX stockfile_date ON stockfile(date);

我建议使用EXPLAIN来分析没有索引的查询,然后一次创建一个索引,然后使用EXPLAIN重新分析,看看哪个索引提供了最直接的好处。

关于sql - 从联接的MySQL表中选择最新条目,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1918827/

10-12 23:03