Sql 选择“最小最大值”将一起改变查询的行为

Sql 选择“最小最大值”将一起改变查询的行为,sql,database,sqlite,Sql,Database,Sqlite,我有一个包含以下列的SQLite表: 时间戳 身份证件 价值 我想编写一个查询,为每个id列出最新的时间戳和该时间戳处的值,以及每个id的最大值 为此,我编写了下面的查询,它按预期工作 SELECT timestamp, MAX(value) as max, id, value from ( SELECT * from temperatures order by timestamp DESC ) GROUP BY ID; 当我现在还想计算最小值时,我修改了查询: SELECT tim

我有一个包含以下列的SQLite表:

时间戳 身份证件 价值 我想编写一个查询,为每个id列出最新的时间戳和该时间戳处的值,以及每个id的最大值

为此,我编写了下面的查询,它按预期工作

SELECT timestamp, MAX(value) as  max, id, value from (
    SELECT * from temperatures order by timestamp DESC
) GROUP BY ID;
当我现在还想计算最小值时,我修改了查询:

SELECT timestamp, MAX(value) as  max, MIN(value) as min, id, value from (
    SELECT * from temperatures order by timestamp DESC
) GROUP BY ID;

现在的问题是时间戳不再是最新的时间戳。为什么会这样?

您的查询格式不正确。选择列表与分组依据不兼容。所以,SQLite所做的是定制处理。是的,查询通过添加另一列改变了含义

我建议您使用窗口函数编写查询:

SELECT id, MIN(timestamp), MAX(timestamp),
       MIN(CASE WHEN timestamp_asc = 1 THEN value END) as temp_at_min,
       MIN(CASE WHEN timestamp_desc = 1 THEN value END) as temp_at_max
FROM (SELECT t.*,
             ROW_NUMBER() OVER (PARTITION BY id ORDER BY timestamp ASC) as seqnum_asc,
             ROW_NUMBER() OVER (PARTITION BY id ORDER BY timestamp ASC) as seqnum_desc
      FROM temperatures t
     ) t
GROUP BY ID;
SELECT DISTINCT id,
  MIN(timestamp) OVER (PARTITION BY id) min_timestamp,
  MAX(timestamp) OVER (PARTITION BY id) max_timestamp,
  FIRST_VALUE(value) OVER (PARTITION BY id ORDER BY timestamp) min,
  FIRST_VALUE(value) OVER (PARTITION BY id ORDER BY timestamp DESC) max  
FROM temperatures

这是标准SQL,应该始终执行您想要的操作。

您可以使用“最小”、“最大”和“第一个值”窗口函数:

SELECT id, MIN(timestamp), MAX(timestamp),
       MIN(CASE WHEN timestamp_asc = 1 THEN value END) as temp_at_min,
       MIN(CASE WHEN timestamp_desc = 1 THEN value END) as temp_at_max
FROM (SELECT t.*,
             ROW_NUMBER() OVER (PARTITION BY id ORDER BY timestamp ASC) as seqnum_asc,
             ROW_NUMBER() OVER (PARTITION BY id ORDER BY timestamp ASC) as seqnum_desc
      FROM temperatures t
     ) t
GROUP BY ID;
SELECT DISTINCT id,
  MIN(timestamp) OVER (PARTITION BY id) min_timestamp,
  MAX(timestamp) OVER (PARTITION BY id) max_timestamp,
  FIRST_VALUE(value) OVER (PARTITION BY id ORDER BY timestamp) min,
  FIRST_VALUE(value) OVER (PARTITION BY id ORDER BY timestamp DESC) max  
FROM temperatures

不需要聚合,窗口函数就足够了。

谢谢。我认为这为我指明了正确的方向。我想我可以使用以下查询:从SELECT t.*中选择id、timestamp、value、MINvalue、MAXvalue,按id按时间戳顺序描述的分区上的行数作为seqnum asc,按id按时间戳顺序描述的分区上的行数作为按id分组的seqnum DESC;看来你没有真正接受别人说的话。如果id是主键,则没有任何按它分组的点。如果它不是主键/比时间戳和值更唯一,那么如果db甚至接受它,则单独按它分组将产生不可预测的结果。如果您说您的第一个查询按预期工作,但此查询不会返回具有最新时间戳的行的值。它返回具有最大值的行的时间戳。