我有一个数据库“库存”与食品项目与以下列:
指数|日期|类别|子范畴|代码|描述|启动|结束
其中“日期”是接收到库存的日期。我想为每个唯一的类别和子类别选择记录,其中“开始”为空,日期是最早的。
我最初的尝试看起来像这样:
SELECT MIN(date) as date, category, subcategory, description, code, inventory.index
FROM inventory
WHERE start is null
GROUP BY category, subcategory
它返回了我想要的每个唯一类别和子类别的记录,但有一些例外。如果稍后添加了一条日期较早的记录(因此,它的索引比日期较晚的记录高),则查询将正确地返回来自该记录的日期,但将返回来自另一条记录的其余列的值,从而创建表中不存在的混合行。这就像“日期”值被不断检查并在必要时更新,但是一旦值被加载到结果中,其他字段就不会改变。我希望有人能帮我弄明白这里发生了什么。
我尝试了其他几种方法:
How to select data where a field has a min value in MySQL?
吴宇森建议在WHERE子句中使用嵌套的SELECT子句。我的看起来像:
SELECT *
FROM inventory
WHERE
( SELECT MIN(date) FROM inventory )
AND
start is null
GROUP BY category, subcategory
AND运算符似乎有问题,它只计算“start is null”条件,而忽略其他条件,不管我把它们放在哪个顺序。当我删除其中一个条件时,另一个条件的计算结果正确。
SQL query to select distinct row with minimum value
Ken Clark建议使用INNER JOIN,我将其修改为:
SELECT inv.*
FROM inventory inv
INNER JOIN
(
SELECT MIN(date) AS date, category, subcategory, description, code, inventory.index
FROM inventory
WHERE start is null
GROUP BY category, subcategory
) inv2
ON inv2.index = inv.index
WHERE inv2.date = inv.date
这种方法返回的结果与我最初的尝试相同,只是省略了有问题的行(我猜是因为在计算最后一个WHERE子句时,日期不同)。
我会很感激任何和所有的建议,我可以了解在这些情况下发生了什么。谢谢你!
2条答案
按热度按时间pkmbmrz71#
这三个查询(最初尝试,然后在
WHERE
子句或JOIN
中使用子查询)都不是有效的标准SQL,因为GROUP BY
和SELECT
子句中的列不一致;在MySQL中,它们只能在禁用ONLY_FULL_GROUP_BY
模式下运行-这不是一个好做法。如果我们要用一个子查询来解决它,我们会像这样将它与外部查询关联起来:
子查询带来您正在查找的当前
category
/subcategory
元组的行的索引,以便外部查询可以在相应的行中进行适当的筛选。如果你运行的是MySQL 8.0(或MariaDB >= 10.2),我推荐使用窗口函数(这样查询就可以在一次表扫描中执行):
8wtpewkr2#
您可以使用字符串连接技巧来获得聚合函数
MIN(date)
的相关列index
,并按类别和子类别分组。一旦你有了所选记录的这些index
值,你就可以连接以获得整行:(假设
date
列是标准的MySQL日期)