从列中选择最大的邮政编码

Selecting the biggest ZIP code from a column

我想获得数据库中最大的邮政编码。通常我这样做

SELECT * 
FROM (
   Select * From tbuser ORDER BY zip DESC
) 
WHERE rownum = 1

使用此代码,我可以获得没有重复行的最大邮政编码值(因为邮政编码不是主键)。

但是日本的主要公司说我不能用它,因为当连接很慢或者数据库有非常大的数据时,你不能得到正确的行。如果有人能提供帮助,那将对我有很大的帮助。

I want to get the biggest ZIP code in DB.

如果您真的想要邮政编码,请尝试:

SELECT MAX(zip) FROM TBUSER;

这将使用 zip 列上的索引(如果存在)。

也就是说,Oracle 通常足够聪明,可以使用 ROWNUM 正确优化子查询选择。也许您的主要公司更关心子查询中可能的 "full table" ̀ORDER BY`? OTH,如果问题真的出在 "slow network",如果您的方法确实导致 "excessive bandwidth consumption",也许值得您的 DBA 花一些时间使用网络分析器或其他工具查看线路。我真的很怀疑...


如果你想检索具有最大邮政编码的整行,这里是 的一个细微变化(在我看来,这是使用 NATURAL JOIN 的罕见情况之一) :

select * from t
natural join (select max(zip) zip from t);

当然,如果出现重复,这将 return 多行。您必须将其与 return 只有 1 行的其他各种答案中发布的几个选项之一结合起来。

作为一个额外的解决方案,并且由于您不允许使用 ROWNUM(并且假设 row_number 也是任意禁止的),您可以使用如下人为设计的方法来达到预期的结果:

select * from t
where rowid = (
  select min(t.rowid) rid from t
  natural join (select max(zip) zip from t)
);

http://sqlfiddle.com/#!4/3bd63/5

但老实说,没有任何严肃的理由希望这种查询比简单的 ... ORDER BY something DESC) WHERE rownum <= 1 查询执行得更好。

这对我来说听起来像是一个不明白他在看什么的新手数据库管理员的糟糕建议(通常伪装成规则)。不过,这种洞察力不会帮助你。以 "you're an obstructionist incompetent" 开头的对话很少能取得任何成果。

所以,事情是这样的。首先,您需要确保 index 在您的 zip 列中。它不一定是主键。

其次,您可以尝试解释 Oracle 的 table 服务器实际上优化了 ... ORDER BY something DESC) WHERE rownum <= 1 查询风格。他们的服务器在这方面做得很好。您的用例很常见。

但如果这对您的 DBA 不起作用,请尝试说 "I heard you" 并执行此操作。

SELECT * FROM (
    SELECT a.* 
      FROM ( SELECT MAX(zip) zip FROM zip ) b
      JOIN ZIP a ON (a.zip = b.zip)
 ) WHERE rownum <= 1

这将得到具有最高编号 zip 值的一行,而没有 ORDER BY,您的 DBA 错误地认为它正在弄乱他的服务器的 RAM 池。而且,它相当有效。只要zip有索引即可。

您的要求似乎很武断,但这应该会给您所要求的结果。

SELECT * 
FROM (SELECT * FROM tbuser 
      WHERE zip = (SELECT MAX(zip) FROM tbuser)) 
WHERE rownum = 1

好的 - 尝试这样的事情:

SELECT *
  FROM TBUSER
  WHERE ZIP = (SELECT MAX(ZIP) FROM TBUSER);

根据上述语句从游标中获取一行,然后关闭游标。如果您使用 PL/SQL,您可以这样做:

FOR aRow IN (SELECT *
               FROM TBUSER
               WHERE ZIP = (SELECT MAX(ZIP) FROM TBUSER))
LOOP
   -- Do something with aRow

   -- then force an exit from the loop

   EXIT;
END LOOP;

分享和享受。

如果您使用 MAX 函数获取多条记录(这是不可能的,但在您的情况下,我不知道如何,直到您 post 屏幕截图)然后您可以在您的中使用 DISTINCT sql查询获取单条记录

SELECT DISTINCT MAX(zipcode) FROM TableUSER

SQL FIDDLE

我想知道还没有人发布这个答案。我认为就是这样,你应该这样做。

SELECT * 
FROM (
   Select a.*, max(zip) over () max_zip
   From tbuser a
) 
WHERE zip=max_zip
and rownum = 1

您的查询恰好获得所有具有最大邮政编码的记录的随机行。因此,您检索带有另一个邮政编码的记录或多个记录或零个记录(只要 table 中至少有一个记录)就不会成为问题。

也许日本只是希望其他行中有该邮政编码?然后,您可能只需要添加另一个订单标准即可获得所需的特定行。

另一个想法:由于他们在谈论连接速度慢,也可能是他们在一个会话中输入一个新的最大邮政编码,与另一个会话查询并获得旧的最大邮政编码,因为另一个的插入语句session 还没有结束。但是,这当然就是它的工作方式。

顺便说一句:select 最大邮政编码很奇怪。我想这只是一个例子来说明问题?

由于您现在正在寻找一种无需 rownum 即可获取所需记录的方法,...

...以下是从 Oracle 12c 开始的操作方法:

select * 
from tbuser
order by zip desc fetch first 1 row only;

... 以下是 Oracle 12c 之前的操作方法:

select * 
from (select tbuser.*, row_number() over(order by zip desc) as rn from tbuser)
where rn = 1;

编辑:正如 Sylvain Leroux 所指出的,对 dbms 来说,对所有记录进行排序而不是仅仅找到最大值需要做更多的工作。这是一个没有 rownum 的最大查询:

select * 
from tbuser where rowid =
(select max(rowid) keep (dense_rank last order by zip) from tbuser);

但是正如 Sylvain Leroux 也提到的,列上是否有索引也有区别。我所做的一些测试表明,使用列上的索引,分析函数比传统函数慢。您的原始查询只会进入索引,转到最高值,选择记录然后停止。你不会更快地得到这个。我最后提到的在 none 索引列上的查询速度比你在索引列上的查询要慢。