SQL - comment sélectionner une ligne ayant une colonne avec une valeur maximale

date                 value

18/5/2010, 1 pm        40
18/5/2010, 2 pm        20
18/5/2010, 3 pm        60
18/5/2010, 4 pm        30
18/5/2010, 5 pm        60
18/5/2010, 6 pm        25 

J'ai besoin d'interroger la ligne ayant max (valeur) (c'est-à-dire 60). Donc, ici, nous avons deux lignes. De cela, j'ai besoin de la ligne avec l'horodatage le plus bas pour ce jour-là (c'est-à-dire 18/5/2010, 3 pm - > 60)

31
demandé sur Mitch Dempsey 2010-05-18 06:40:38

9 réponses

Mots-clés comme TOP, LIMIT, ROWNUM,...etc sont dépendants de la base de données. Veuillez lire cet article pour plus d'informations.

Http://en.wikipedia.org/wiki/Select_(SQL) # Result_limits

Oracle: ROWNUM pourrait être utilisé.

select * from (select * from table 
order by value desc, date_column) 
where rownum = 1;

Répondre à la question plus spécifiquement:

select high_val, my_key
from (select high_val, my_key
      from mytable
      where something = 'avalue'
      order by high_val desc)
where rownum <= 1
42
répondu Sujee 2012-08-28 03:01:46

Analyse! Cela évite d'avoir à accéder à la table deux fois:

SELECT DISTINCT
       FIRST_VALUE(date_col)  OVER (ORDER BY value_col DESC, date_col ASC),
       FIRST_VALUE(value_col) OVER (ORDER BY value_col DESC, date_col ASC)
FROM   mytable;
27
répondu Jeffrey Kemp 2010-05-18 04:04:24

Réponse est d'ajouter une clause having:

SELECT [columns]
FROM table t1
WHERE value= (select max(value) from table)
AND date = (select MIN(date) from table t2 where t1.value = t2.value)

Cela devrait fonctionner et se débarrasser de la nécessité d'avoir une sous-sélection supplémentaire dans la clause date.

7
répondu TerrorAustralis 2010-05-18 03:54:32
SQL> create table t (mydate,value)
  2  as
  3  select to_date('18/5/2010, 1 pm','dd/mm/yyyy, hh am'), 40 from dual union all
  4  select to_date('18/5/2010, 2 pm','dd/mm/yyyy, hh am'), 20 from dual union all
  5  select to_date('18/5/2010, 3 pm','dd/mm/yyyy, hh am'), 60 from dual union all
  6  select to_date('18/5/2010, 4 pm','dd/mm/yyyy, hh am'), 30 from dual union all
  7  select to_date('18/5/2010, 5 pm','dd/mm/yyyy, hh am'), 60 from dual union all
  8  select to_date('18/5/2010, 6 pm','dd/mm/yyyy, hh am'), 25 from dual
  9  /

Table created.

SQL> select min(mydate) keep (dense_rank last order by value) mydate
  2       , max(value) value
  3    from t
  4  /

MYDATE                   VALUE
------------------- ----------
18-05-2010 15:00:00         60

1 row selected.

Cordialement, Rob.

6
répondu Rob van Wijk 2010-05-18 08:04:25

Dans Oracle:

Cela obtient la clé du max (high_val) dans la table en fonction de la plage.

select high_val, my_key
from (select high_val, my_key
      from mytable
      where something = 'avalue'
      order by high_val desc)
where rownum <= 1
2
répondu Eric Leschinski 2012-08-28 02:49:02

Techniquement, c'est la même réponse que @Sujee. Cela dépend également de votre version D'Oracle quant à savoir si cela fonctionne. (Je pense que cette syntaxe a été introduite dans Oracle 12??)

SELECT *
FROM   table
ORDER BY value DESC, date_column ASC
FETCH  first 1 rows only;

Comme je le dis, si vous regardez sous le capot, je pense que ce code est déballé en interne par L'Optimiseur Oracle pour lire comme celui de @ Sujee. cependant, je suis une ventouse pour le joli codage, et imbriquer select déclarations sans une bonne raison ne se qualifie pas comme beau!! :- P

1
répondu cartbeforehorse 2018-05-30 12:42:51

La réponse La plus simple serait

-- Configuration d'une table de test appelée " t1 "

create table t1
(date datetime,
value int)

-- charge les données. -- Remarque: le format de date différent de celui de la question

insert into t1
Select '5/18/2010 13:00',40
union all
Select '5/18/2010 14:00',20
union all
Select '5/18/2010 15:00',60 
union all
Select '5/18/2010 16:00',30 
union all
Select '5/18/2010 17:00',60 
union all
Select '5/18/2010 18:00',25 

-- trouvez la ligne avec la quantité max et la date min.

select *
from t1
where value = 
    (select max(value)  from t1)
and date = 
    (select min(date) 
    from t1
    where value = (select max(value)  from t1))

Je sais que vous pouvez faire la réponse "TOP 1", mais généralement votre solution devient juste assez compliquée pour que vous ne puissiez pas l'utiliser pour une raison quelconque.

0
répondu JBrooks 2010-05-18 03:11:52

Dans Oracle DB:

create table temp_test1 (id number, value number, description varchar2(20));

insert into temp_test1 values(1, 22, 'qq');
insert into temp_test1 values(2, 22, 'qq');
insert into temp_test1 values(3, 22, 'qq');
insert into temp_test1 values(4, 23, 'qq1');
insert into temp_test1 values(5, 23, 'qq1');
insert into temp_test1 values(6, 23, 'qq1');

SELECT MAX(id), value, description FROM temp_test1 GROUP BY value, description;

Result:
    MAX(ID) VALUE DESCRIPTION
    -------------------------
    6         23    qq1
    3         22    qq
0
répondu shrinath 2018-02-17 02:11:41

Vous pouvez utiliser cette fonction, Oracle DB

 public string getMaximumSequenceOfUser(string columnName, string tableName, string username)
    {
        string result = "";
        var query = string.Format("Select MAX ({0})from {1} where CREATED_BY = {2}", columnName, tableName, username.ToLower());

        OracleConnection conn = new OracleConnection(_context.Database.Connection.ConnectionString);
        OracleCommand cmd = new OracleCommand(query, conn);
        try
        {
            conn.Open();
            OracleDataReader dr = cmd.ExecuteReader();
            dr.Read();
            result = dr[0].ToString();
            dr.Dispose();
        }
        finally
        {
            conn.Close();
        }
        return result;
    }
-2
répondu Nada N. Hantouli 2017-04-11 06:14:21