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

Sql 从列中选择最大的邮政编码,sql,oracle,greatest-n-per-group,Sql,Oracle,Greatest N Per Group,我想得到DB中最大的邮政编码。通常我这样做 SELECT * FROM ( Select * From tbuser ORDER BY zip DESC ) WHERE rownum = 1 有了这个代码,我可以在没有重复行的情况下获得最大的邮政编码值(因为邮政编码不是主键) 但是日本的主要公司说我不能使用它,因为当连接速度慢或者数据库有非常大的数据时,你不能得到正确的数据行。如果有人能帮助我,那将是一个很大的帮助 我想得到DB中最大的邮政编码 如果您确实只想要邮政编码,请尝试: S

我想得到DB中最大的邮政编码。通常我这样做

SELECT * 
FROM (
   Select * From tbuser ORDER BY zip DESC
) 
WHERE rownum = 1
有了这个代码,我可以在没有重复行的情况下获得最大的邮政编码值(因为邮政编码不是主键)

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

我想得到DB中最大的邮政编码

如果您确实只想要邮政编码,请尝试:

SELECT MAX(zip) FROM TBUSER;
这将使用
zip
列上的索引(如果存在)

也就是说,Oracle通常足够聪明,可以使用
ROWNUM
正确地优化子查询选择。也许您的主要公司更关心子查询中可能出现的“完整表”̀orderby `?另外,如果问题真的是“网络速度慢”,那么如果您的方法真的导致“带宽消耗过多”,那么可能值得您的DBA花一些时间使用网络分析仪或其他工具查看线路。我真的对此表示怀疑


如果您想检索具有最大邮政编码的整行,这里有一个小小的变化(在我看来,这是使用
自然连接的罕见情况之一)

当然,如果是重复的,这将返回多行。您必须将其与各种其他答案中发布的几个选项之一结合起来,才能只返回一行

作为一种额外的解决方案,由于您不允许使用
ROWNUM
(并且假设
row\u number
也是任意禁止的),因此您可以通过以下方式实现所需的结果:

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


但老实说,没有任何严肃的理由希望这样的查询比简单的
执行得更好。。。按某物排序(DESC),其中rownum对我来说,这听起来像是一个新手数据库管理员的坏建议(伪装成规则),他不明白自己在看什么。但是,这种洞察力对你没有帮助。以“你是个无能的阻碍者”开头的对话很少能取得任何效果

事情是这样的。首先,您需要确保在
zip
列上有一个索引。它不必是主键


其次,您可以尝试解释Oracle的表服务器实际上优化了
。。。按某物排序(DESC),其中rownum您的要求似乎是任意的,但这应该会给出您所要求的结果

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);
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;
根据上述语句从游标中获取一行,然后关闭游标。如果您使用的是PL/SQL,您可以这样做:

SELECT *
  FROM TBUSER
  WHERE ZIP = (SELECT MAX(ZIP) FROM TBUSER);
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函数获取多条记录(这是不可能的,但在您的情况下,我不知道如何获取,直到您发布屏幕截图),那么您可以在sql查询中使用DISTINCT来获取单条记录

SELECT DISTINCT MAX(zipcode) FROM TableUSER

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

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

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

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

另一个想法是:当他们谈论连接速度慢时,也可能是他们在一个会话上输入一个新的max zip代码,与另一个会话进行查询并获取旧的max zip,因为另一个会话的insert语句尚未完成。当然,这就是它的工作方式


顺便说一句:选择最大邮政编码是件奇怪的事情。我想这只是一个例子来说明问题?

当您正在寻找一种方法来获得所需的记录而不需要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的max查询:

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

但正如Sylvain Leroux也提到的那样,列上是否有索引也会产生差异。我做的一些测试表明,如果列上有索引,分析函数比传统函数慢。您的原始查询将进入索引,转到最高值,选择记录,然后停止。你不会再快了。我上一次提到的在无索引列上的查询速度比在索引列上的查询速度慢。

坦白说,这听起来像是一个错误的限制。但是您使用的是哪种Oracle版本?连接速度慢不会对此产生影响。Oracle将只向运行该语句的程序传回一行。你要么理解了错误的地方(关于连接速度慢的部分),要么就是说你不知道Oracle是如何处理查询的。我不知道为什么,但日本的主要公司说了这个问题,并要求我们使用其他方法。我们很可能通过互联网与日本DB连接。如果表真的很大,为什么不
分区
它?”但日本的主要公司说我不能使用它,因为连接很慢或者DB有很大的数据,“阅读您的各种评论——真正的问题不是“如何在不可靠的连接上检索大行吗?”谢谢您的回答Sylvain Leroux。但SELECT Max的主要问题是,如果我有两个最大的邮政编码,如“99800”,它也会同时显示两行。@Nguyen“如果我有两个最大的邮政编码,如“99800”,它也会同时显示两行”--不,不会:@SylvainLeroux,我不知道为什么,但它会显示两行