在SQLite中将术语排除在GROUP BY之外?
当我开始使用SQLite时,我注意到GROUP BY允许您在其中保留未汇总的术语。例如:在SQLite中将术语排除在GROUP BY之外?,sql,sqlite,Sql,Sqlite,当我开始使用SQLite时,我注意到GROUP BY允许您在其中保留未汇总的术语。例如: SELECT month, category, max(quantity) from Table1 GROUP BY month; 这将给我一个输出,在那里我得到每月的最大数量,但我也得到了类别的值 类别到底给了我什么?它是否为我提供了映射到当月最大数量的类别,而我通常必须通过自联接来完成该类别?或者是完全任意的,如果是完全任意的,为什么他们不给我一个错误,而不是让我认为我的查询是有效的 我会忽略这样一个
SELECT month, category, max(quantity)
from Table1
GROUP BY month;
这将给我一个输出,在那里我得到每月的最大数量,但我也得到了类别的值
类别到底给了我什么?它是否为我提供了映射到当月最大数量的类别,而我通常必须通过自联接来完成该类别?或者是完全任意的,如果是完全任意的,为什么他们不给我一个错误,而不是让我认为我的查询是有效的
我会忽略这样一个事实,即它让我这样做是一种疏忽,除非我发现他们似乎利用了这样一个事实,即你可以通过将术语从小组中删除,除非我误解了教程
编辑我也尝试了一下,发现下面的两个查询提供了完全相同的输出:
这两个查询都在查找每个cust_id的maxupdate_at值,然后还输出该cust_id的段
使用自联接的查询1:
利用SQLite的怪癖进行愚蠢的SQLite查询:
那么,它们返回的结果完全相同,这只是巧合吗?还是我遗漏了什么?我反复运行第二个版本,看看它是否会给我不同的结果,每次都会给我相同的结果。来源:
...
然后,对每组行对结果集中的每个表达式求值一次。如果表达式是聚合表达式,则将跨组中的所有行对其求值。否则,将根据组内任意选择的一行对其进行评估。如果结果集中有多个非聚合表达式,则对同一行计算所有此类表达式。
...
因此,是的,您仅从组中随机选择的行中获取值
为什么会这样?很可能是因为SQLite的设计者/程序员决定这样做。可能是因为这更容易和/或他们不认为这很重要。顺便说一句,和MySQL用户一样,至少在较低版本或某些设置中也是如此。SQLite允许聚合查询中的裸列与MySQL兼容。您需要,所以只有当您知道这些值在一个组中实际上是相同的时,这才有用 但是,有一个适用于您的案例: 当在聚合查询中使用最小或最大聚合函数时,结果集中的所有裸列都从同样包含最小或最大值的输入行中获取值
所以你的查询一定会成功。我就是这么想的。但是,如果我正确地编写了查询,而不是错误地编写了查询,那么为什么会得到相同的结果呢?我很恼火,因为我注意到我得到了我想要的结果,我开始使用SQLite版本的GroupBy作为我提交的一个练习中的一个快捷方式,结果证明现在是完全错误的:/@andraiamatrix:正如你已经猜到的,这是巧合。很抱歉,但这是可能的。测试以及仅仅或主要基于几个示例的问题描述总是有遗漏某些内容的风险。因此CL在sqlite文档中找到了答案:对于max和min,它实际上给出了相应的值,这就是我使用它的方式。但这可能不是一个好习惯。令人惊讶的是,SQLite中的查询甚至可以编译。我认为只有MySQL允许它,因为它不是有效的ANSI SQL。我知道的每一个RBDM都会以这样的声明失败。谢谢!!我现在觉得自己被证实了,哈哈。我在一次技术采访中利用了这一点,他们让我使用SQLite,他们认为这是不正确的,就像我第一次发现它时一样。但我对self-join的结果进行了多次验证,并不断得到正确的答案。
SELECT seg.cust_id, seg.seg_name, temp.max_update
FROM segments as seg
INNER JOIN
(
SELECT cust_id, MAX(update_at) AS max_update
FROM segments
WHERE DATE(update_at) <= "2016-03-01"
GROUP BY cust_id
) as temp
ON
seg.cust_id = temp.cust_id AND
seg.update_at = temp.max_update;
SELECT cust_id,seg_name, MAX(update_at)
FROM segments
WHERE DATE(update_at) <= "2016-03-01"
GROUP BY cust_id;