子查询:我做错了什么?

Subqueries: What am I doing fundamentally wrong?

我认为从 SQL 中的子查询中选择值只会从该子集中生成值,直到我在代码中发现一个非常讨厌的错误。这是我的问题的一个例子。

  1. 我正在按日期选择包含最新(最大)函数的行。这正确 returns 4 行,每个函数的最新签入。

    select *, max(date) from cm where file_id == 5933 group by function_id;
    
file_id function_id 日期值最大值(日期)
5933 64807 1407941297 1 1407941297
5933 64808 1407941297 11 1407941297
5933 895175 1306072348 1306072348
5933 895178 1363182349 1363182349
  1. 当仅从上面的子集中选择值时,它 returns 以前日期的函数值,即不属于上面子集的行。您可以在下面看到结果,其中日期比第一个子集中的日期早。

    select temp.function_id, temp.date, temp.value
    from (select *, max(date)
          from cm
          where file_id 5933
          group by function_id) as temp;
    
function_id 日期值

64807 1306072348 1 <-outdated 行,不在第一个子集中
64808 1306072348 17 <-outdated 行,不在第一个子集中
895175 1306072348
895178 1363182349

我做错了什么?不应该仅对子查询执行选择 return 这些子查询的可能结果吗?

您似乎忽略了一个事实,即您的子查询正在返回给定 file_id 的所有行。如果您想将子查询限制为最近日期的记录,则需要使用 WHERE NOT EXISTS 子句来限制它,以检查给定条件下是否不存在更多最近的记录。

SQLite 允许您使用 MAX() 来 select 由 GROUP BY 返回的行,但这只有在实际计算 MAX() 时才有效。 当您丢弃 max(date) 列时,这将不再有效。

在这种情况下,您实际上想要使用 date 值,因此您可以只保留 MAX():

SELECT function_id,
       max(date) AS date,
       value
FROM cm
WHERE file_id = 5933
GROUP BY function_id

也许我的问题表述不正确,但是这个 post 提供了我主要寻找的解决方案:

过滤掉最近的行是我的问题。我很惊讶从具有最大值的子查询中选择可能会产生除该值以外的任何东西。