我遇到了以下SYBASE SQL:
-- Setup first create table #t (id int, ts int) go insert into #t values (1, 2) insert into #t values (1, 10) insert into #t values (1, 20) insert into #t values (1, 30) insert into #t values (2, 5) insert into #t values (2, 13) insert into #t values (2, 25) go declare @time int select @time=11 -- This is the SQL I am asking about select * from (select * from #t where ts <= @time) t group by id having ts = max(ts) go
该SQL的结果是
id ts ----------- ----------- 1 10 2 5
这看起来像是将HAVING条件应用于行而不是组。有人可以帮我指出描述这种情况的地方是Sybase 15.5文档吗?我所看到的只是“在团队中运作”。我在文档中看到的最接近的是:
hading子句可以包括不在选择列表中且不在group by子句中的列或表达式。
(从这里引用)。
但是,他们没有完全解释当您这样做时会发生什么。
我的理解:是的,从根本上说,HAVING在行上进行操作。通过省略GROUP BY,它可以对单个“超组”中的所有结果行进行操作,而不是对组内行进行操作。请阅读原始链接的Sybase docco中的 “分组方式以及如何使用聚合进行查询” 一节:
如何对汇总进行分组并进行查询 在 这里 子句排除不符合其搜索条件的行; 对于分组查询或非分组查询,其功能保持不变。 对于 group by 表达式中的每个唯一值, group by 子句将剩余的行收集到一组中。省略 group by 将为整个表创建单个组。 在选择列表中指定的集合函数计算每个组的摘要值。对于标量聚合,表只有一个值。向量集合可计算不同组的值。 在 其 条款中排除组从那些不符合其搜索条件的结果。即使 having 子句仅测试行,但 group by 子句的存在或不存在可能会使它似乎在组上运行: 当查询包括 group by时 , 将 排除结果组行。这就是为什么 有 好像在团体开展工作。 如果查询没有 分组依据 ,则查询结果将从(单组)表 中 排除。这就是为什么 有 似乎对行进行操作(的结果是相似的 ,其中 条款的结果)。
如何对汇总进行分组并进行查询
其次,在“ having,groupby和where子句如何相互作用”部分中有一个简短的摘要:
具有,分组依据和where子句如何相互作用 当在查询中包含 having , group by 和 where 子句时,每个子句影响行的顺序将确定最终结果: 在 这里 子句排除不符合其搜索条件的行。 对于 group by 表达式中的每个唯一值, group by 子句将剩余的行收集到一组中。 在选择列表中指定的集合函数计算每个组的摘要值。 将 其 从那些不符合其搜索条件的最终结果子句排除行。
具有,分组依据和where子句如何相互作用
当在查询中包含 having , group by 和 where 子句时,每个子句影响行的顺序将确定最终结果:
@SQLGuru的解释就是对此的说明。
与此相关的是,我对使用TSQL“扩展列”的不符合ANSI的查询的行为感到惊讶。Sybase处理 (i) WHERE子句之后的扩展列 ( ii) 通过创建到原始表的额外联接,以及 (iii) 联接中未使用WHERE子句。这样的查询可能返回比预期更多的行,并且HAVING子句随后需要附加条件才能将其过滤掉。
请参阅原始链接的docco页面上的 “用于分组并具有的Transact-SQL扩展” 下的示例 b , c 和 d 。我发现从Sybase安装 pubs2 示例数据库与示例一起使用非常有用。