通过键获取最小值/最大值-不同的方法

时间:2019-07-09 08:59:28

标签: sql sql-server sql-order-by

我有一个包含两列的表,即ID和KEY(这里的键为整数),例如

ID KEY
ABC 6
DEF 1
GHI 12

任务:获取MAX键的ID

解决方案1:

Select Top(1) ID
from TABLE
order by KEY desc

解决方案2:

Select ID
from TABLE 
where ID = MAX(ID)

编辑:查询无效。这就是我的意思:

Select ID
from TABLE 
where KEY = (select max(KEY) from TABLE)

这些解决方案中的一种绝对优于另一种吗?每种解决方案的优缺点是什么?

编辑: 假设没有索引。 案例1-大桌子 案例2-小桌子

背景: 我正在进行代码审查,并且在不同的上下文中多次找到这两种解决方案-有时带有索引,有时没有索引,有时是大表,有时是小表。

5 个答案:

答案 0 :(得分:1)

除非聚集在HAVING子句或选择列表中包含的子查询中,否则聚集可能不会出现在WHERE子句中。

解决方案1将是最好的。 where子句中的子查询将不是最佳选择。 确实有很多设计技术可以用来研究性能,我不会在这个答案中讨论。我昨天发现这篇文章,这给了我更多的见解https://www.red-gate.com/simple-talk/sql/database-administration/sql-server-storage-internals-101/

答案 1 :(得分:1)

在解决方案1中,order by子句只会对您的查询结果进行排序。 查询执行顺序:

FROM子句ON子句OUTER子句WHERE子句GROUP BY子句HAVING子句SELECT子句DISTINCT子句ORDER BY子句TOP子句

您可以使用以下查询:

Select ID,
RANK() OVER (ORDER BY KEY DESC) AS KeyRank
from table1
HAVING keyRank = 1

答案 2 :(得分:1)

这两个查询是不同的(在修改第二个查询之后)。

第一个必须返回一行。

第二个返回 all 个匹配行。

即使key为NULL,第一个也返回一行。

第二个没有。

您应该使用符合您想要的逻辑。

答案 3 :(得分:0)

解决方案1可以工作,但是解决方案2会像下面这样抛出异常

  

消息147,级别15,状态1,第22行聚合可能不会出现在   WHERE子句,除非它位于HAVING子句中包含的子查询中   或选择列表,并且要聚合的列是外部   参考。

答案 4 :(得分:0)

您可以查询1,

您不能使用查询2,因为您不能使用类似的聚合函数,如果您想在查询中使用where子句和聚合函数,则必须遵循以下条件:

Select id  from table where key in (select max(key) from test);

引用仅使用聚合函数并具有子句

Select  ID ,max(key)
   from test
   group by ID,key
   having (key) >= 12
    order by 1