Sqlite 在group by子句中包含非聚合列(带有轻微褶皱)

Sqlite 在group by子句中包含非聚合列(带有轻微褶皱),sqlite,group-by,aggregate-functions,Sqlite,Group By,Aggregate Functions,我有一张像这样的桌子: timestamp value person =============================================== 2010-01-12 00:00:00 33 emp1 2010-01-12 11:00:00 22 emp1 2010-01-12 09:00:00 16 emp2 2

我有一张像这样的桌子:

timestamp                value           person
===============================================
2010-01-12 00:00:00       33              emp1
2010-01-12 11:00:00       22              emp1
2010-01-12 09:00:00       16              emp2
2010-01-12 08:00:00       16              emp2
2010-01-12 12:12:00       45              emp3
2010-01-12 13:44:00       64              emp4
2010-01-12 06:00:00       33              emp1
2010-01-12 15:00:00       12              emp5
我想找到与每个人相关的最大值。显而易见的疑问是:

select person,max(value) from table group by person
现在我想包括与每个max(值)关联的时间戳。我不能在上面的查询中使用timestamp列,因为众所周知,它不会出现在GROUPBY子句中。所以我写了这个:

select x.timestamp,x.value,x.person from table as x,
(select person,max(value) as maxvalue from table group by person order by maxvalue 
 desc) as y
where x.person = y.person
and x.value = y.maxvalue
这在某种程度上是有效的。我现在看到:

timestamp                value           person
===============================================
2010-01-12 13:44:00       64              emp4
2010-01-12 12:12:00       45              emp3
2010-01-12 06:00:00       33              emp1
2010-01-12 00:00:00       33              emp1
2010-01-12 08:00:00       16              emp2
2010-01-12 09:00:00       16              emp2
2010-01-12 15:00:00       12              emp5
现在的问题是,我得到的emp1和emp2的所有条目的最大值都相同

假设在emp1和emp2中,我只想看到带有最新时间戳的条目。瞧,我想要这个:

timestamp                value           person
===============================================
2010-01-12 13:44:00       64              emp4
2010-01-12 12:12:00       45              emp3
2010-01-12 06:00:00       33              emp1
2010-01-12 09:00:00       16              emp2
2010-01-12 15:00:00       12              emp5
我需要写什么样的查询?是否有可能扩展我编写的嵌套查询以实现我想要的结果,还是必须从头重写所有内容

如果它很重要,因为我使用的是Sqlite,那么时间戳实际上存储为julian days。我使用datetime()函数将它们转换回每个查询中的字符串表示形式。

您几乎做到了:

SELECT max(x.timestamp) AS timestamp, x.value, x.person
     , y.max_value, y.ct_value, y.avg_value
FROM   table AS x
JOIN  (
    SELECT person
         , max(value) as max_value
         , count(value) as ct_value
         , avg(value) as avg_value
    FROM   table
    GROUP  BY person
    ) AS y ON (x.person, x.value) = (y.person, y.max_value)
GROUP BY x.person, x.value, y.max_value, y.ct_value, y.avg_value
-- ORDER  BY x.person, x.value
您不能在同一嵌套查询中计算
max(x.timestamp)
,因为您不想要每个人的绝对最大值,而是要最大值所伴随的值。因此,您必须在下一查询级别上聚合另一个时间

计算
max(x.timestamp)
,然后再将其转换为字符串表示形式——尽管您的格式也会正确排序。但这应该表现得更好

请注意,我是如何将带有where条件的交叉联接转换为带有(简化的)联接条件的[内部]联接的。做同样的事情,更像是SQL标准的规范方式,更具可读性

所有这些都可以通过窗口函数(
max()
first\u value()
)在一个查询级别完成,这些函数在所有较大的RDBMS(MYSQL除外)中实现,但不在SQLite中实现


编辑
在评论中包括请求后的附加聚合。

非常感谢。这也是我达到的目的,但有点挠头。我能问另外一个问题吗?如果我想保留您上面写的所有内容,但同时还要执行count(value)、avg(value)以及按avg(value)排序结果集,会发生什么情况?说明:我的意思是除了看到当前时间戳、max(value)和person列之外,我还想在同一个查询中看到count(value)和avg(value)。正如你所知道的,sql不是我的强项,我可能正在为一些基本的东西而挣扎@Dilip:您可以将
计数(值)
平均值(值)
添加到内部
选择
。我修改了我的答案来证明。非常感谢。这一切对我来说都开始有意义了