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