在Mariadb子查询中LIMIT的行为

问题描述 投票:0回答:2

这是我的问题。

我在SQL查询方面不是很好,所以我希望能够深入了解LIMIT子句的不同行为。我有两个问题。让我们说我的桌子有3列,namedatedate_modified。我每小时修改一次表格并使用date_modified列对其进行修订。我正在尝试获取特定日期2017-12-12修改日期的最后一条记录(最近修改过)。

SELECT * from 
   (SELECT * from table where name in ('name1','name2','name3') 
    and date in ('2017-12-12') order by date_modified desc)
    as tmp_table group by name

SELECT * from 
   (SELECT * from table where name in ('name1','name2','name3') 
    and date in ('2017-12-12') order by date_modified desc LIMIT 100)
    as tmp_table group by name

第一个返回一个表,其中修改的日期是当天最早的记录。第二个是我想要的,它返回最新修改的数据。如果我有一个更大的表,其中name3是第101个记录,查询将无法正常工作。所以对LIMIT进行硬编码既不可行又不好。

为什么会有区别?订单是否在子查询中不起作用?

*我只是在添加其他信息,因为我自己想到了一个解决方案。

添加:上面的子查询具有相同的行为;即根据修改的日期按降序对数据进行排序。

date_modifieddate都是日期时间格式。

sql mariadb greatest-n-per-group
2个回答
0
投票

表是一组无序数据。对于派生表,即子查询,情况也是如此。

第一个查询

您从表中选择某些记录并对其进行排序。 DBMS可以完全忽略这个ORDER BY子句,因为您只将数据用作子查询。

然后按名称分组。现在我们必须区分两种情况:

  1. name + date在表中是独一无二的。然后你准确地返回你找到的行。 GROUP BY条款将是多余的。
  2. name + date在表中并不是唯一的。但你select *。这是无效的SQL,因为如果您有一个名称和日期的多行,则不会告诉DBMS要选择哪些值。如果MariaDB让这个失败,那就是DBMS中的一个缺陷。

根据您的描述,似乎第二种情况适用。您的查询无效。

第二个查询

您可以从表中选择某些记录并对其进行排序,以便应用LIMIT子句。这限制了结果,但DBMS可以自由地以任何顺序输出行,因为您将数据用作子查询。当您通过date_modified订购时,您可以从结果中丢弃一些名称(例如,所有name1和name2的最后一百条记录,当然您将解雇name3。

至于GROUP BY name:关于第一个查询,我所说的内容也适用于此。您将数据限制为100行没有任何区别。


0
投票

这不是你问题的真正答案。请参阅我的其他答案,了解您的查询有什么问题以及您对其行为的假设。


我想你想要的是这个,2017年12月12日每个名字的最新条目:

select *
from
(
  select 
    t.*, 
    max(date_modified) over (partition by name) as max_date_modified
  from t
  where name in ('name1', 'name2', 'name3') 
  and date in (date '2017-12-12')
) numbered
where date_modified = max_date_modified
order by name;

更新:似乎MariaDB还不支持MAX OVERhttps://mariadb.com/kb/en/library/aggregate-functions-as-window-functions/)。所以使用ROW_NUMBER代替:

select *
from
(
  select 
    t.*, 
    row_number() over (partition by Name order by date_modified desc) as rn
  from t
  where name in ('name1', 'name2', 'name3') 
  and date in (date '2017-12-12')
) numbered
where rn = 1
order by name;
© www.soinside.com 2019 - 2024. All rights reserved.