获取 MAX(date) < X 的数据

Posted

技术标签:

【中文标题】获取 MAX(date) < X 的数据【英文标题】:Get data where MAX(date) < X 【发布时间】:2016-08-08 14:25:34 【问题描述】:

我有两个具有一对多关系的表。

Table1
ID name email
Table2
ID table1_ID date

我需要从 Table1 where 获取所有数据:

MAX(date) from Table2 < "2016-01-01"

这不起作用。 Max 在 where 子句中被视为“无效”。我所做的是:

SELECT Table1.name, Table1.email, tmp.maxdate
FROM Table1
JOIN (  SELECT  MAX(date) maxdate, table1_ID
        FROM    Table2
        GROUP BY table1_ID ) as tmp
    ON  tmp.table1_ID = table1.id
WHERE   tmp.maxdate < "2016-01-01"
AND     (other conditions)

所以这行得通。但是我认为性能会很糟糕——explain 表明所有的Table2 都在被读取,并且这个表会增长很多。

知道我该怎么做,或者如何提高我当前的查询性能?

【问题讨论】:

为什么你认为性能很糟糕? 将 tmp 加入 table1 有点奇怪,而不是将 tmp 加入表 2 的中间步骤。另外,我将 WHERE 子句放在子查询中。除此之外,经过适当索引,此查询应该非常快。 由于MAX(date)是一个聚合,它不能放在WHERE中,而是属于HAVING。无论如何,正如其他人指出的那样,您可以简单地使用 WHERE date &gt; '2016-01-01' 而不是 HAVING MAX(date) &gt; '2016-01-01' @Strawberry 好吧,要将 tmp 加入到 Table2 我还必须将 Table2 加入到查询中,这不是一个无用的连接,因为除了已经来自的表之外,我没有使用该表时间?另外,很好的一点是,将where date &gt; X 添加到子查询中会对性能有所帮助。 如果您愿意,请考虑遵循以下简单的两步操作: 1. 如果您还没有这样做,请提供适当的 CREATE 和 INSERT 语句(和/或 sqlfiddle),以便我们可以更容易复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。 【参考方案1】:

试试:

SELECT Table1.name, Table1.email, tmp.maxdate
FROM Table1
INNER JOIN (  SELECT  MAX(date) maxdate, table1_ID
        FROM    Table2
        GROUP BY table1_ID
        HAVING maxdate > "2016-01-01" ) as tmp
    ON  tmp.table1_ID = table1.id
WHERE   
AND     (other conditions)

以前,您只是将 Table2 中的每个人都带回来并与 Table1 一起加入。这将淘汰所有没有 maxdate >“2016-01-01”的人,并使用 Table1 加入它。

【讨论】:

这是一个很好的观点,@Strawberry 在 cmets 中也指出了这一点,谢谢!【参考方案2】:

首先,别想了,自己测试检查一下。

其次,您可以尝试使用 EXISTS(),这可能会稍微快一些,因为您可以过滤 Table2 而不是使用 GROUP BY 子句:

SELECT * FROM Table1 t1
WHERE EXISTS(SELECT 1 FROM Table2 t2
             WHERE t2.date > "2016-01-01"
               AND t1.id = t2.table1_id
               AND <Other Conditions>)

您还可以在子查询中添加table2.date &gt; "2016-01-01"

此外,考虑添加以下索引:

Table1(id,name,email)
Table2(table1_id,date)

请注意,我根据您提供的查询推荐这些索引,如果有额外的条件,这些索引可能不完整。

【讨论】:

您好,感谢您的回答!当然索引设置正确。你有一个非常有趣的观点,仍然存在。我不认为它真的适合其他强制性点(按 maxdate 排序,限制结果集),但我会尝试使用它一会儿。

以上是关于获取 MAX(date) < X 的数据的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 查询基于连接条件和 max(date) 获取属性

Spark 2.0 groupBy 列,然后在 datetype 列上获取 max(date)

获取 min(date) AND max(date) 及其各自的标题

MySQL 查询仅获取一条记录:当 end_date 为 null 或 max(end_date) 时

如何在一行中获取这些数据

python获取mq队列数据报Queue.declare: (406) PRECONDITION_FAILED - inequivalent arg ‘x-max-priority‘