{"id":601,"date":"2005-03-13T18:00:00","date_gmt":"2005-03-14T01:00:00","guid":{"rendered":"http:\/\/kodegeek.com\/blog\/?p=601"},"modified":"2005-03-13T18:00:00","modified_gmt":"2005-03-14T01:00:00","slug":"echando-codigo-%c2%bfcomo-encontrar-el-mayor-numero-en-una-tabla-usando-sql-sin-usar-funciones-de-agregacion-max-min","status":"publish","type":"post","link":"http:\/\/kodegeek.com\/blog\/2005\/03\/13\/echando-codigo-%c2%bfcomo-encontrar-el-mayor-numero-en-una-tabla-usando-sql-sin-usar-funciones-de-agregacion-max-min\/","title":{"rendered":"Echando c\u00f3digo: \u00bfComo encontrar el mayor n\u00famero en una tabla (usando SQL), sin usar funciones de agregaci\u00f3n (max, min)?"},"content":{"rendered":"<p>Esta es otra de las preguntas con las cuales pueden tratar de matarlo en una entrevista:<\/p>\n<blockquote><p>\u00bfComo encontrar el mayor n\u00famero en una tabla (usando SQL), <span style=\"font-style: italic;\">sin usar funciones de agregaci\u00f3n<\/span> (max, min)?<\/p><\/blockquote>\n<p>Hmmm. \u00bfInteresante, no es as\u00ed?. La pregunta busca ver sus conocimientos b\u00e1sicos de SQL y como ataca problemas.<\/p>\n<p>Primero, antes de empezar a resolver este problema, vamos a hacer un par de preparativos, ya que la idea es que usted lo haga frente a un computador; As\u00ed que si no tiene instalado <a href=\"http:\/\/www.postgresql.org\/docs\/7.4\/interactive\/index.html\">PostgreSQL<\/a> 7.4 y <a href=\"http:\/\/java.sun.com\/\">Java<\/a> le recomiendo que lo haga, as\u00ed como tambien deber\u00eda crear una base de dados para pruebas la cual llamaremos &#8216;test&#8217;:<br \/>Ahora vamos a crear las tablas necesarias para resolver el problema y vamos a llenarlas con datos.<\/p>\n<blockquote><p><span style=\"color: rgb(0, 153, 0);\">[root@localhost pgsql]# createdb &#8211;user=postgres test &#8211;host=localhost.localdomain<br \/>CREATE DATABASE<br \/>psql &#8211;user=postgres &#8211;host=localhost.localdomain test &#8211;file src\/sql\/create_tables.sql<br \/>CREATE TABLE<\/p>\n<p>[josevnz@localhost SQLProblem]$ <span style=\"color: rgb(0, 153, 0);\">cat src\/sql\/create_tables.sql<\/span><br \/><span style=\"color: rgb(255, 0, 0);\"> \/* <\/span><br \/><span style=\"color: rgb(255, 0, 0);\">  * Test table that will hold our numbers and names. <\/span><br \/><span style=\"color: rgb(255, 0, 0);\">  * Author: Jose V Nunez Z <\/span><br \/><span style=\"color: rgb(255, 0, 0);\">  * Blog: El Angel Negro &#8211; http:\/\/elangelnegro.blogspot.com <\/span><br \/><span style=\"color: rgb(255, 0, 0);\">  * License: GPL <\/span><br \/><span style=\"color: rgb(255, 0, 0);\">  *\/ <\/span><br \/><span style=\"color: rgb(255, 0, 0);\">&#8212; Table with users <\/span><br \/><span style=\"color: rgb(255, 0, 0);\">create table users ( <\/span><br \/><span style=\"color: rgb(255, 0, 0);\">   ages int not null, <\/span><br \/><span style=\"color: rgb(255, 0, 0);\">   names varchar(15) <\/span><br \/><span style=\"color: rgb(255, 0, 0);\">);<\/span><\/span><\/p><\/blockquote>\n<p>Y ahora vamos a llenarlas de datos, usando un programita en Java que genera n\u00fameros aleatorios, los cuales pueden estar repetidos:<\/p>\n<style type=\"text\/css\"><!-- .syntax0 { color: #000000; } .syntax1 { color: #cc0000; } .syntax2 { color: #ff8400; } .syntax3 { color: #6600cc; } .syntax4 { color: #cc6600; } .syntax5 { color: #ff0000; } .syntax6 { color: #9966ff; } .syntax7 { background: #ffffcc; color: #ff0066; } .syntax8 { color: #006699; font-weight: bold; } .syntax9 { color: #009966; font-weight: bold; } .syntax10 { color: #0099ff; font-weight: bold; } .syntax11 { color: #66ccff; font-weight: bold; } .syntax12 { color: #02b902; } .syntax13 { color: #ff00cc; } .syntax14 { color: #cc00cc; } .syntax15 { color: #9900cc; } .syntax16 { color: #6600cc; } .syntax17 { color: #0000ff; } .syntax18 { color: #000000; font-weight: bold; } .gutter { background: #dbdbdb; color: #000000; } .gutterH { background: #dbdbdb; color: #990066; } --><br \/><\/style>\n<p><\/p>\n<pre><span class=\"gutter\">   1:<\/span><span class=\"syntax9\">import<\/span> java.sql.SQLException;<br \/><span class=\"gutter\">   2:<\/span><span class=\"syntax9\">import<\/span> java.sql.PreparedStatement;<br \/><span class=\"gutter\">   3:<\/span><span class=\"syntax9\">import<\/span> java.sql.Statement;<br \/><span class=\"gutter\">   4:<\/span><span class=\"syntax9\">import<\/span> java.sql.DriverManager;<br \/><span class=\"gutterH\">   5:<\/span><span class=\"syntax9\">import<\/span> java.sql.ResultSet;<br \/><span class=\"gutter\">   6:<\/span><span class=\"syntax9\">import<\/span> java.sql.Connection;<br \/><span class=\"gutter\">   7:<\/span><br \/><span class=\"gutter\">   8:<\/span><span class=\"syntax9\">import<\/span> java.util.Random;<br \/><span class=\"gutter\">   9:<\/span><br \/><span class=\"gutterH\">  10:<\/span><span class=\"syntax9\">import<\/span> java.util.ResourceBundle;<br \/><span class=\"gutter\">  11:<\/span><br \/><span class=\"gutter\">  12:<\/span><span class=\"syntax3\">\/**<\/span><br \/><span class=\"gutter\">  13:<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">*<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">This<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">program<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">generates<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">a<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">series<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">of<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">random<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">numbers<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">for<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">our<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">problem<\/span><span class=\"syntax3\">.<\/span><br \/><span class=\"gutter\">  14:<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">*<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax12\">@author<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">Jose<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">V<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">Nunez<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">Z<\/span><br \/><span class=\"gutterH\">  15:<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">*<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax12\">@version<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">0<\/span><span class=\"syntax3\">.<\/span><span class=\"syntax3\">1<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">-<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">03<\/span><span class=\"syntax3\">\/<\/span><span class=\"syntax3\">09<\/span><span class=\"syntax3\">\/<\/span><span class=\"syntax3\">2005<\/span><br \/><span class=\"gutter\">  16:<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">*<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax12\">@see<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">http<\/span><span class=\"syntax3\">:<\/span><span class=\"syntax3\">\/<\/span><span class=\"syntax3\">\/<\/span><span class=\"syntax3\">elangelnegro<\/span><span class=\"syntax3\">.<\/span><span class=\"syntax3\">blogspot<\/span><span class=\"syntax3\">.<\/span><span class=\"syntax3\">com<\/span><br \/><span class=\"gutter\">  17:<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">*\/<\/span><br \/><span class=\"gutter\">  18:<\/span><span class=\"syntax8\">public<\/span> <span class=\"syntax8\">final<\/span> <span class=\"syntax10\">class<\/span> GenerateNumbers <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  19:<\/span><br \/><span class=\"gutterH\">  20:<\/span>        <span class=\"syntax8\">private<\/span> <span class=\"syntax8\">static<\/span> <span class=\"syntax8\">final<\/span> ResourceBundle BUNDLE <span class=\"syntax18\">=<\/span><br \/><span class=\"gutter\">  21:<\/span>                ResourceBundle.<span class=\"syntax6\">getBundle<\/span>(GenerateNumbers.<span class=\"syntax10\">class<\/span>.<span class=\"syntax6\">getName<\/span>());<br \/><span class=\"gutter\">  22:<\/span><br \/><span class=\"gutter\">  23:<\/span>        <span class=\"syntax3\">\/**<\/span><br \/><span class=\"gutter\">  24:<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">*<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">Program<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">entry<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">routine<\/span><br \/><span class=\"gutterH\">  25:<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">*<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax12\">@param<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">args<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">-<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">Ignored<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">for<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">now<\/span><br \/><span class=\"gutter\">  26:<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">*<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax12\">@throws<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">Exception<\/span><br \/><span class=\"gutter\">  27:<\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\"> <\/span><span class=\"syntax3\">*\/<\/span><br \/><span class=\"gutter\">  28:<\/span>        <span class=\"syntax8\">public<\/span> <span class=\"syntax8\">static<\/span> <span class=\"syntax10\">void<\/span> <span class=\"syntax6\">main<\/span>(String [] args) <span class=\"syntax8\">throws<\/span> Exception <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  29:<\/span>                Connection con <span class=\"syntax18\">=<\/span> <span class=\"syntax14\">null<\/span>;<br \/><span class=\"gutterH\">  30:<\/span>                Statement stat <span class=\"syntax18\">=<\/span> <span class=\"syntax14\">null<\/span>;<br \/><span class=\"gutter\">  31:<\/span>                PreparedStatement prep <span class=\"syntax18\">=<\/span> <span class=\"syntax14\">null<\/span>;<br \/><span class=\"gutter\">  32:<\/span>                Random rand <span class=\"syntax18\">=<\/span> <span class=\"syntax8\">new<\/span> <span class=\"syntax6\">Random<\/span>();<br \/><span class=\"gutter\">  33:<\/span>                <span class=\"syntax10\">int<\/span> max <span class=\"syntax18\">=<\/span> <span class=\"syntax5\">0<\/span>;<br \/><span class=\"gutter\">  34:<\/span>                <span class=\"syntax8\">try<\/span> <span class=\"syntax18\">{<\/span><br \/><span class=\"gutterH\">  35:<\/span>                        max <span class=\"syntax18\">=<\/span> Integer.<span class=\"syntax6\">parseInt<\/span>(BUNDLE.<span class=\"syntax6\">getString<\/span>(<span class=\"syntax13\">\"<\/span><span class=\"syntax13\">maxNumbers<\/span><span class=\"syntax13\">\"<\/span>));<br \/><span class=\"gutter\">  36:<\/span>                        Class.<span class=\"syntax6\">forName<\/span>(BUNDLE.<span class=\"syntax6\">getString<\/span>(<span class=\"syntax13\">\"<\/span><span class=\"syntax13\">driver<\/span><span class=\"syntax13\">\"<\/span>));<br \/><span class=\"gutter\">  37:<\/span>                        con <span class=\"syntax18\">=<\/span> DriverManager.<span class=\"syntax6\">getConnection<\/span>(<br \/><span class=\"gutter\">  38:<\/span>                                BUNDLE.<span class=\"syntax6\">getString<\/span>(<span class=\"syntax13\">\"<\/span><span class=\"syntax13\">url<\/span><span class=\"syntax13\">\"<\/span>),<br \/><span class=\"gutter\">  39:<\/span>                                BUNDLE.<span class=\"syntax6\">getString<\/span>(<span class=\"syntax13\">\"<\/span><span class=\"syntax13\">user<\/span><span class=\"syntax13\">\"<\/span>),<br \/><span class=\"gutterH\">  40:<\/span>                                BUNDLE.<span class=\"syntax6\">getString<\/span>(<span class=\"syntax13\">\"<\/span><span class=\"syntax13\">password<\/span><span class=\"syntax13\">\"<\/span>)<br \/><span class=\"gutter\">  41:<\/span>                        );<br \/><span class=\"gutter\">  42:<\/span>                        stat <span class=\"syntax18\">=<\/span> con.<span class=\"syntax6\">createStatement<\/span>();<br \/><span class=\"gutter\">  43:<\/span>                        stat.<span class=\"syntax6\">executeUpdate<\/span>(<span class=\"syntax13\">\"<\/span><span class=\"syntax13\">truncate<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">table<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">users<\/span><span class=\"syntax13\">\"<\/span>);<br \/><span class=\"gutter\">  44:<\/span>                        stat.<span class=\"syntax6\">close<\/span>();<br \/><span class=\"gutterH\">  45:<\/span>                        prep <span class=\"syntax18\">=<\/span> con.<span class=\"syntax6\">prepareStatement<\/span>(<span class=\"syntax13\">\"<\/span><span class=\"syntax13\">INSERT<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">INTO<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">users(ages,<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">names)<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">VALUES(?,<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">'dumb')<\/span><span class=\"syntax13\">\"<\/span>);<br \/><span class=\"gutter\">  46:<\/span>                        <span class=\"syntax8\">for<\/span> (<span class=\"syntax10\">int<\/span> i<span class=\"syntax18\">=<\/span><span class=\"syntax5\">0<\/span>; i <span class=\"syntax18\">&lt;<\/span> max; i<span class=\"syntax18\">+<\/span><span class=\"syntax18\">+<\/span>) <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  47:<\/span>                                prep.<span class=\"syntax6\">setInt<\/span>(<span class=\"syntax5\">1<\/span>, rand.<span class=\"syntax6\">nextInt<\/span>(i<span class=\"syntax18\">+<\/span><span class=\"syntax5\">1<\/span>));<br \/><span class=\"gutter\">  48:<\/span>                                prep.<span class=\"syntax6\">executeUpdate<\/span>();<br \/><span class=\"gutter\">  49:<\/span>                                prep.<span class=\"syntax6\">clearParameters<\/span>();<br \/><span class=\"gutterH\">  50:<\/span>                        <span class=\"syntax18\">}<\/span><br \/><span class=\"gutter\">  51:<\/span>                        prep.<span class=\"syntax6\">close<\/span>();<br \/><span class=\"gutter\">  52:<\/span>                <span class=\"syntax18\">}<\/span> <span class=\"syntax8\">catch<\/span> (SQLException sqlex) <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  53:<\/span>                        <span class=\"syntax8\">throw<\/span> sqlex;<br \/><span class=\"gutter\">  54:<\/span>                <span class=\"syntax18\">}<\/span> <span class=\"syntax8\">catch<\/span> (NumberFormatException nfexp) <span class=\"syntax18\">{<\/span><br \/><span class=\"gutterH\">  55:<\/span>                        <span class=\"syntax8\">throw<\/span> nfexp;<br \/><span class=\"gutter\">  56:<\/span>                <span class=\"syntax18\">}<\/span> <span class=\"syntax8\">finally<\/span> <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  57:<\/span>                        <span class=\"syntax8\">if<\/span> (stat <span class=\"syntax18\">!<\/span><span class=\"syntax18\">=<\/span> <span class=\"syntax14\">null<\/span>) <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  58:<\/span>                                <span class=\"syntax8\">try<\/span> <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  59:<\/span>                                        stat.<span class=\"syntax6\">close<\/span>();<br \/><span class=\"gutterH\">  60:<\/span>                                <span class=\"syntax18\">}<\/span> <span class=\"syntax8\">catch<\/span> (SQLException ignore) <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  61:<\/span>                                        <span class=\"syntax2\">\/\/<\/span><span class=\"syntax2\"> <\/span><span class=\"syntax2\">Empty<\/span><br \/><span class=\"gutter\">  62:<\/span>                                <span class=\"syntax18\">}<\/span>;<br \/><span class=\"gutter\">  63:<\/span>                        <span class=\"syntax18\">}<\/span><br \/><span class=\"gutter\">  64:<\/span>                        <span class=\"syntax8\">if<\/span> (prep <span class=\"syntax18\">!<\/span><span class=\"syntax18\">=<\/span> <span class=\"syntax14\">null<\/span>) <span class=\"syntax18\">{<\/span><br \/><span class=\"gutterH\">  65:<\/span>                                <span class=\"syntax8\">try<\/span> <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  66:<\/span>                                        prep.<span class=\"syntax6\">close<\/span>();<br \/><span class=\"gutter\">  67:<\/span>                                <span class=\"syntax18\">}<\/span> <span class=\"syntax8\">catch<\/span> (SQLException ignore) <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  68:<\/span>                                        <span class=\"syntax2\">\/\/<\/span><span class=\"syntax2\"> <\/span><span class=\"syntax2\">Empty<\/span><br \/><span class=\"gutter\">  69:<\/span>                                <span class=\"syntax18\">}<\/span>;<br \/><span class=\"gutterH\">  70:<\/span>                        <span class=\"syntax18\">}<\/span><br \/><span class=\"gutter\">  71:<\/span>                        <span class=\"syntax8\">if<\/span> (con <span class=\"syntax18\">!<\/span><span class=\"syntax18\">=<\/span> <span class=\"syntax14\">null<\/span>) <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  72:<\/span>                                <span class=\"syntax8\">try<\/span> <span class=\"syntax18\">{<\/span><br \/><span class=\"gutter\">  73:<\/span>                                        con.<span class=\"syntax6\">close<\/span>();<br \/><span class=\"gutter\">  74:<\/span>                                <span class=\"syntax18\">}<\/span> <span class=\"syntax8\">catch<\/span> (SQLException ignore) <span class=\"syntax18\">{<\/span><br \/><span class=\"gutterH\">  75:<\/span>                                        <span class=\"syntax2\">\/\/<\/span><span class=\"syntax2\"> <\/span><span class=\"syntax2\">Empty<\/span><br \/><span class=\"gutter\">  76:<\/span>                                <span class=\"syntax18\">}<\/span>;<br \/><span class=\"gutter\">  77:<\/span>                        <span class=\"syntax18\">}<\/span><br \/><span class=\"gutter\">  78:<\/span>           <br \/><span class=\"gutter\">  79:<\/span>                <span class=\"syntax18\">}<\/span><br \/><span class=\"gutterH\">  80:<\/span>        <span class=\"syntax18\">}<\/span><br \/><span class=\"gutter\">  81:<\/span><span class=\"syntax18\">}<\/span><br \/><\/pre>\n<p>En SQL normal, usted s\u00f3lo tendr\u00eda que hacer esto para hallar al n\u00famero m\u00e1s grande:<\/p>\n<blockquote style=\"color: rgb(204, 0, 0);\"><p>select max(ages) from users<\/p><\/blockquote>\n<p>Eso nos d\u00e1 el n\u00famero <span style=\"font-style: italic;\">9872<\/span> (para mi corrida de ejemplo). Vamos a pensar un poco como hacerlo sin esta funci\u00f3n.<\/p>\n<p>Lo primero que se me ocurri\u00f3 es limitar la cantidad de resultados que vienen desde la base de datos. Con Java es trivial pero si lo quiero hacer con SQL entonces puedo usar la sintaxis propia de PostgreSQL:<\/p>\n<blockquote><p>test=# <span style=\"color: rgb(0, 153, 0);\">select ages from users order by ages desc limit 1;<\/span><br \/>ages<br \/>&#8212;&#8212;<br \/><span style=\"font-style: italic;\">9872<\/span><br \/>(1 row)<\/p>\n<p>test=# explain select ages from users order by ages desc limit 1;<br \/>                        QUERY PLAN<br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>Limit  (<span style=\"font-weight: bold;\">cost=69.83<\/span>..69.83 rows=1 width=4)<br \/>->  Sort  (cost=69.83..72.33 rows=1000 width=4)<br \/>    Sort Key: ages<br \/>    ->  Seq Scan on users  (cost=0.00..20.00 rows=1000 width=4)<br \/>(4 rows)<\/p>\n<p>test=#<\/p><\/blockquote>\n<p>No est\u00e1 tan mal. Otra forma es iterar por todos los resultados, sin ordernarlos y a medida que vamos obteniendo los resultados guardamos el valor de el n\u00famero s\u00f3lo si es mayor que el anterior. Asi no ordenamos, pero quizas la sobrecarga de esta operaci\u00f3n es muy grande; Lo \u00fanico es que debemos cargar el lenguaje &#8216;pgsql&#8217; en la nueva base de datos, de lo contrario no podremos crear stored procedures:<\/p>\n<blockquote><p>[josevnz@localhost lib]$ <span style=\"color: rgb(0, 153, 0);\">createlang plpgsql test &#8211;user=postgres &#8211;host localhost.localdomain<\/span><\/p><\/blockquote>\n<p>El c\u00f3digo en plpgsql:<\/p>\n<style type=\"text\/css\"><!-- .syntax0 { color: #000000; } .syntax1 { color: #cc0000; } .syntax2 { color: #ff8400; } .syntax3 { color: #6600cc; } .syntax4 { color: #cc6600; } .syntax5 { color: #ff0000; } .syntax6 { color: #9966ff; } .syntax7 { background: #ffffcc; color: #ff0066; } .syntax8 { color: #006699; font-weight: bold; } .syntax9 { color: #009966; font-weight: bold; } .syntax10 { color: #0099ff; font-weight: bold; } .syntax11 { color: #66ccff; font-weight: bold; } .syntax12 { color: #02b902; } .syntax13 { color: #ff00cc; } .syntax14 { color: #cc00cc; } .syntax15 { color: #9900cc; } .syntax16 { color: #6600cc; } .syntax17 { color: #0000ff; } .syntax18 { color: #000000; font-weight: bold; } .gutter { background: #dbdbdb; color: #000000; } .gutterH { background: #dbdbdb; color: #990066; } --><br \/><\/style>\n<p><\/p>\n<pre><span class=\"gutter\">13:<\/span><span class=\"syntax1\">--<\/span><span class=\"syntax1\"> <\/span><span class=\"syntax1\">Another<\/span><span class=\"syntax1\"> <\/span><span class=\"syntax1\">solution:<\/span><span class=\"syntax1\"> <\/span><span class=\"syntax1\">Use<\/span><span class=\"syntax1\"> <\/span><span class=\"syntax1\">a<\/span><span class=\"syntax1\"> <\/span><span class=\"syntax1\">cursor<\/span><span class=\"syntax1\"> <\/span><span class=\"syntax1\">and<\/span><span class=\"syntax1\"> <\/span><span class=\"syntax1\">some<\/span><span class=\"syntax1\"> <\/span><span class=\"syntax1\">programming<\/span><br \/><span class=\"gutter\">14:<\/span><span class=\"syntax8\">CREATE<\/span> <span class=\"syntax8\">OR<\/span> <span class=\"syntax9\">REPLACE<\/span> <span class=\"syntax8\">FUNCTION<\/span> <span class=\"syntax6\">getmax<\/span>() <span class=\"syntax8\">RETURNS<\/span> <span class=\"syntax8\">integer<\/span> <span class=\"syntax8\">AS<\/span> <span class=\"syntax13\">'<\/span><br \/><span class=\"gutterH\">15:<\/span><span class=\"syntax13\">DECLARE<\/span><br \/><span class=\"gutter\">16:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">biggest<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">integer<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">:=<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">0;<\/span><br \/><span class=\"gutter\">17:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">curr<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">integer<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">:=<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">0;<\/span><br \/><span class=\"gutter\">18:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">curs<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">CURSOR<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">FOR<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">SELECT<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">ages<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">FROM<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">users;<\/span><br \/><span class=\"gutter\">19:<\/span><span class=\"syntax13\">BEGIN<\/span><br \/><span class=\"gutterH\">20:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">OPEN<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">curs;<\/span><br \/><span class=\"gutter\">21:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">FETCH<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">curs<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">INTO<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">curr;<\/span><br \/><span class=\"gutter\">22:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">WHILE<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">FOUND<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">LOOP<\/span><br \/><span class=\"gutter\">23:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">IF<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">curr<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">&gt;<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">biggest<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">THEN<\/span><br \/><span class=\"gutter\">24:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">biggest<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">:=<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">curr;<\/span><br \/><span class=\"gutterH\">25:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">END<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">IF;<\/span><br \/><span class=\"gutter\">26:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">FETCH<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">curs<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">INTO<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">curr;<\/span><br \/><span class=\"gutter\">27:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">END<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">LOOP;<\/span><br \/><span class=\"gutter\">28:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">CLOSE<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">curs;<\/span><br \/><span class=\"gutter\">29:<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">return<\/span><span class=\"syntax13\"> <\/span><span class=\"syntax13\">biggest;<\/span><br \/><span class=\"gutterH\">30:<\/span><span class=\"syntax13\">END;<\/span><br \/><span class=\"gutter\">31:<\/span><span class=\"syntax13\">'<\/span> LANGUAGE plpgsql;<br \/><\/pre>\n<p>Y la salida de ejemplo:<br \/>test=# select getmax();<br \/>getmax<br \/>&#8212;&#8212;&#8211;<br \/> 9872<br \/>(1 row)<\/p>\n<p>En teoria el <span style=\"font-style: italic;\">stored procedure<\/span> deber\u00eda ser m\u00e1s eficiente que la salida anterior, ya que no hay que ordenar toda la tabla para luego sacar el primero de ese resultado.<\/p>\n<p>Finalmente, esta soluci\u00f3n la consegu\u00ed en un libro:<\/p>\n<blockquote><p>&#8212; This answer doesn&#8217;t work at all&#8230;<br \/>SELECT<br \/>distinct ages<br \/>FROM<br \/>users<br \/>WHERE<br \/>ages NOT IN (<br \/><span style=\"color: rgb(255, 0, 0);\">              SELECT a.ages FROM users a, users b WHERE a.ages<\/span>).<\/p><\/blockquote>\n<p>Seg\u00fan PostgreSQL esto es lo que el query va a hacer:<\/p>\n<blockquote><p>                                  QUERY PLAN<br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>Unique  (<span style=\"font-weight: bold;\">cost=11712.41<\/span>..11714.91 rows=100 width=4)<br \/>->  Sort  (cost=11712.41..11713.66 rows=500 width=4)<br \/>   Sort Key: ages<br \/>   ->  Seq Scan on users a  (cost=0.00..11690.00 rows=500 width=4)<br \/>         Filter: (NOT (subplan))<br \/>         SubPlan<br \/>           ->  Seq Scan on users b  (cost=0.00..22.50 rows=334 width=4)<br \/>                 Filter: ($0 < test=\"\">.<\/p><\/blockquote>\n<p>El costo es altisimo, adem\u00e1s de que el query nunca finaliza ya que la secci\u00f3n en rojo genera un n\u00famero exagerado de combinaciones&#8230;<\/p>\n<p>Por cierto, el costo de usar la funci\u00f3n de agregaci\u00f3n &#8216;max&#8217; es el menor de todas las alternativas (la rutina est\u00e1 bien optimizada):<\/p>\n<blockquote><p>test=# <span style=\"color: rgb(0, 102, 0);\">explain select max(ages) from users;<\/span><br \/>                     QUERY PLAN<br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>Aggregate  (<span style=\"font-weight: bold;\">cost=22.50<\/span>..22.50 rows=1 width=4)<br \/>->  Seq Scan on users  (cost=0.00..20.00 rows=1000 width=4)<br \/>(2 rows)<\/p>\n<p>test=#<\/p><\/blockquote>\n<p>Si usted conoce otra soluci\u00f3n a este problema, mucho se lo agradecer\u00e9. Estuve pensandolo por un tiempo pero s\u00f3lo pude llegar a esto :D. Tambi\u00e9n le dejo un enlace a un <a href=\"http:\/\/www.postgresql.org\/files\/documentation\/books\/aw_pgsql\/node3.html\">buen libro de PostgreSQL<\/a>.<\/p>\n<p>Se puede bajar todo el \u0107odigo desde <a href=\"http:\/\/prdownloads.sourceforge.net\/elangelnegro\/SQLProblem.tar.gz?download\">aqu\u00ed<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Esta es otra de las preguntas con las cuales pueden tratar de matarlo en una entrevista: \u00bfComo encontrar el mayor n\u00famero en una tabla (usando SQL), sin usar funciones de agregaci\u00f3n (max, min)? Hmmm. \u00bfInteresante, no es as\u00ed?. La pregunta busca ver sus conocimientos b\u00e1sicos de SQL y como ataca problemas. Primero, antes de empezar <a class=\"read-more\" href=\"http:\/\/kodegeek.com\/blog\/2005\/03\/13\/echando-codigo-%c2%bfcomo-encontrar-el-mayor-numero-en-una-tabla-usando-sql-sin-usar-funciones-de-agregacion-max-min\/\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[],"tags":[],"_links":{"self":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/601"}],"collection":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/comments?post=601"}],"version-history":[{"count":0,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/601\/revisions"}],"wp:attachment":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/media?parent=601"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/categories?post=601"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/tags?post=601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}