我有一个数据库"Inventory",其中包含以下各列的食品:

索引|日期|类别|子类别|代码|说明|开始|结束

其中"日期"是接收到库存中的日期.我想 for each 唯一的类别和子类别 Select 记录,其中"Start"为空,日期是最早的.

我最初的try 是这样的:

SELECT MIN(date) as date, category, subcategory, description, code, inventory.index
    FROM inventory 
    WHERE start is null
    GROUP BY category, subcategory

它返回了我想要的每个唯一类别和子类别的记录,但有几个例外.如果添加的记录的日期较早(因此,它的索引高于日期较晚的记录),则查询将正确地返回该记录中的日期,但将返回其余列的另一个记录中的值,从而创建一个表中不存在的混合行.这就像"日期"值被连续判断并在必要时更新,但其他字段在将值加载到结果中后不会更改.我希望有人能帮我了解这里发生的事情.

我try 了其他几种方法:

How to select data where a field has a min value in MySQL?

John Woo建议在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建议使用内部联接,我将其修改为:

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

这种方法返回与我最初try 相同的结果,只是省略了有问题的行(我猜是因为在计算最后的WHERE子句时日期不同).

如果有任何建议,我可以在哪里了解这些案件中发生的事情,我将不胜感激.谢谢!

推荐答案

SELECT MIN(date) as date, category, subcategory, description, code, inventory.index
FROM inventory 
WHERE start is null
GROUP BY category, subcategory

这三个查询(最初try ,然后在WHERE子句或JOIN中使用子查询)都不是有效的标准SQL,因为GROUP BYSELECT子句中的列不一致;在MySQL中,它们只能在禁用模式ONLY_FULL_GROUP_BY的情况下运行--这不是好做法.

如果我们使用子查询来解决它,我们会将它与外部查询关联起来,如下所示:

select * 
from inventory i
where i.index = (
    select i1.index 
    from inventory i1 
    where i1.category = i.category and i1.subcategory = i.subcategory and i1.start is null 
    order by i1.date, i1.index limit 1
)

子查询为当前的category/subcategory元组带来您要查找的行的索引,以便外部查询可以正确地过滤相应的行.

如果您运行的是MySQL 8.0(或MariaDB&>=10.2),我建议您改用窗口函数(以便可以在单个表扫描中执行查询):

select *
from (
    select i.*, 
        row_number() over(partition by category, subcategory order by i.date, i.index) rn
    from inventory i
    where start is null
) t
where rn = 1

Sql相关问答推荐

在SQL Server中使用LEFT连接包含特定记录

当有空单元格时,如何连接列

SQL查询组类值在同一行中,并连接和排序其他值

更新在两个或多个面中具有交点的面

如何在SQL Server中列出从当前月份开始的过go 10年中的月份

SQL查询每个客户的最新条目

有没有办法用SQL编写一条CASE语句,如果列A&>0,那么列B,列C=0

SQL:如何在表中同时使用GROUPING和CONDITION?

重用传递给 node 的参数-postgres upsert查询

优化Postgres搜索未知长度的子串

如何在AWS Athena中 Select JSON数组的最后一个元素?

获取分布在同一行的列中的出现次数

具有分组条件的不同计数 (DAX)

SQL 搜索 - 获取最大值日期的奇怪行为

如何优化仅返回符合条件的三条记录的查询?

创建定时器以更新Gridview

PostgreSQL如何将Unix纪元时间戳转换为日期时间并进行拼接

根据潜在空值的条件对记录进行计数

Snowflake 中的对象是如何比较的?

Django only() 和 values() 不适用于 prefetch_related()