web-dev-qa-db-fra.com

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 pour la ligne ayant max (valeur) (c'est-à-dire 60). Donc, ici nous avons deux rangées. À partir de là, j'ai besoin de la rangée dont l'horodatage est le plus bas pour ce jour (18/5/2010, 15h -> 60)

35
Abhishek

Les mots clés tels que TOP, LIMIT, ROWNUM, ... etc dépendent 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
47
Sujee

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

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;
28
Jeffrey Kemp
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.

7
Rob van Wijk

La réponse est d'ajouter une clause has:

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 éliminer la nécessité d'avoir une sous-sélection supplémentaire dans la clause de date.

7
TerrorAustralis

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
Eric Leschinski

Techniquement, c'est la même réponse que @Sujee. Cela dépend également de votre version d'Oracle pour 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 disais, si vous regardez sous le capot, je pense que ce code est décompressé en interne par Oracle Optimizer pour se lire comme @ Sujee. Cependant, je suis un ventouse pour le joli codage, et imbriquer des déclarations select sans une bonne raison ne peut être qualifié de beau !! :-P

2
cartbeforehorse

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
shrinath

La réponse la plus simple serait

- Configurez une table de test appelée "t1"

create table t1
(date datetime,
value int)

- Chargez les données .-- Remarque: le format de date est différent de celui indiqué dans 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 

- Trouver la ligne avec la date de quantité maximale et minimale.

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 répondre au "TOP 1", mais généralement, votre solution est suffisamment compliquée pour que vous ne puissiez pas l'utiliser pour une raison quelconque.

0
JBrooks