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)
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
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;
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.
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.
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
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
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.
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
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;
}