【问题标题】:Subqueries: What am I doing fundamentally wrong?子查询:我做错了什么?
【发布时间】:2023-04-01 03:28:02
【问题描述】:

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

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

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

    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 &lt-过时的行,不在第一个子集中 64808 1306072348 17 &lt-过时的行,不在第一个子集中 895175 1306072348 895178 1363182349

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

【问题讨论】:

  • 我认为问题在于您按 function_id 对行集进行分组,同时保留行的其他字段。尝试添加您的 GROUP BY 的其他非聚合(最大/计数/最小)字段。如果它们是不必要的,请不要将它们保留在您的 SELECT 语句中。

标签: sql sqlite subquery subset


【解决方案1】:

SQLite 允许您使用 MAX() 选择由 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

【讨论】:

  • 那么带有分组依据的子查询返回所有行,而不仅仅是最大日期行?我在问为什么不一致,我认为查询子查询只会返回该子查询的结果。
  • 子查询返回随机行,每组一个。
  • 所以它不返回最大日期的行?
  • 如果 max() 列实际上没有返回,则不保证这样做。
【解决方案2】:

您似乎错过了您的子查询返回给定 file_id 的所有行的事实。如果您想将子查询限制为具有最近日期的 recs,则需要使用 WHERE NOT EXISTS 子句对其进行限制,以检查给定条件是否不存在更多最近的记录。

【讨论】:

  • 但是子查询好像只返回4行?给我一个 WHERE NOT EXISTS 子句的例子。
【解决方案3】:

也许我的问题表述不正确,但这篇文章提供了我一直在寻找的解决方案:

https://stackoverflow.com/a/123481/2966951

https://stackoverflow.com/a/121435/2966951

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多