代码之家  ›  专栏  ›  技术社区  ›  EMP

在sqlite group by query的选择列表中包含额外的列是否安全?

  •  2
  • EMP  · 技术社区  · 15 年前

    我有一个名为“message”的简单sqlite表:

    sequence INTEGER PRIMARY KEY
    type TEXT
    content TEXT
    

    我想获取每种类型的最后一条消息的内容(由其序列决定)。令我惊讶的是,以下简单查询工作正常:

    SELECT MAX(sequence), type, content
    FROM message
    GROUP BY type
    

    令人惊讶的是,因为我知道mssql或postgres会拒绝在选择列表中包含不属于group by子句或聚合函数的列,而我必须执行一个join,如下所示:

    SELECT m.sequence, m.type, m.content
    FROM
    (
        SELECT MAX(sequence) as sequence, type
        FROM message
        GROUP BY type
    ) g
    JOIN message m
    ON g.sequence = m.message_sequence
    

    我的问题是:在sqlite中使用第一种更简单的查询形式是否安全?从直观上讲,它选择与“max(sequence)”值匹配的“content”值是有意义的,但是文档似乎根本没有讨论这个问题。当然,如果序列不是唯一的,那么结果将是未定义的。但是,如果序列是唯一的,就像在我的例子中一样,这是有保证的,还是仅仅是一个幸运的实现细节可能会发生变化?

    3 回复  |  直到 9 年前
        1
  •  6
  •   Bill Karwin    15 年前

    SELECT c.parent_id, COUNT(*), p.any_column
    FROM child_table c 
    JOIN parent_table p USING (parent_id)
    GROUP BY c.parent_id;
    

    p.any_column


    content sequence

    SELECT MAX(sequence), MIN(sequence), type, content
    FROM message
    GROUP BY type
    

    date 内容 ?

    SELECT MAX(date), type, content
    FROM message
    GROUP BY type
    

    其他的聚合函数呢 AVG() SUM() ?聚合值可能与表中的任何单独行都不对应。那么现在应该为哪个行提供值 内容 ?

    SELECT AVG(sequence), type, content
    FROM message
    GROUP BY type
    
        2
  •  1
  •   Alison R.    15 年前

    我不知道有哪一个数据库能“直观地”解决这类问题,在这种情况下,您需要根据特定列的聚合结果来获取组的相关行值。对于sqlite,我认为您最好坚持第二个查询。

    既然您提到了postgresql,那么值得注意的是它支持一些非标准语法,这些语法以distinct on的形式实现了这一点:

    select distinct on (type) sequence, type, content
    from message
    order by sequence desc
    

    (可能有一些错误,因为我前面没有psql提示,但这就是要点。)

    http://www.postgresql.org/docs/8.4/interactive/queries-select-lists.html

        3
  •  0
  •   Dmitry    15 年前

    我敢打赌它只是对序列字段使用一个随机值。例如,mysql文档明确地这么说。