这是我的问题。
我在SQL查询方面不是很好,所以我希望能够深入了解LIMIT子句的不同行为。我有两个问题。可以说我的表有3列,name
,date
和date_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_modified
和date
都采用日期时间格式。
答案 0 :(得分:0)
表是一组无序数据。对于派生表,即子查询,情况也是如此。
首次查询
您可以从表中选择某些记录并对其进行排序。 DBMS可以完全忽略这个ORDER BY
子句,因为您只将数据用作子查询。
然后按名称分组。现在我们必须区分两种情况:
name
+ date
在表格中是唯一的。然后你准确地返回你找到的行。 GROUP BY
条款将是多余的。 name
+ date
在表格中不是唯一的。但是你select *
。这是无效的SQL,因为如果您有一个名称和日期的多行,则不会告诉DBMS要选择哪些值。如果MariaDB让这个漏掉了,那就是DBMS中的一个缺陷。根据您的描述,似乎第二种情况适用。您的查询无效。
第二次查询
您可以从表格中选择某些记录并对其进行排序,以便应用LIMIT
子句。这限制了结果,但DBMS可以自由地以任何顺序输出行,因为您将数据用作子查询。当您按date_modified
订购时,您可能会从结果中丢弃一些名称(例如,所有name1和name2的最后一百条记录,然后您当然会忽略name3。
至于GROUP BY name
:关于第一个查询我所说的内容也适用于此。将数据限制为100行没有任何区别。
答案 1 :(得分: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 OVER
(https://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;