Comment retourner 1 valeur par ligne du maximum de plusieurs colonnes :
Nom de la table
[Number, Date1, Date2, Date3, Cost]
J'ai besoin de rendre quelque chose comme ça :
[Number, Most_Recent_Date, Cost]
Une requête ?
Comment retourner 1 valeur par ligne du maximum de plusieurs colonnes :
Nom de la table
[Number, Date1, Date2, Date3, Cost]
J'ai besoin de rendre quelque chose comme ça :
[Number, Most_Recent_Date, Cost]
Une requête ?
Voici une autre solution intéressante pour le Max
à l'aide de T-SQL et de SQL Server
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
Les valeurs sont les suivantes Constructeur de valeur de tableau .
"Spécifie un ensemble d'expressions de valeur de ligne à construire dans une table. Le constructeur de valeurs de table Transact-SQL permet de spécifier plusieurs lignes de données dans une seule instruction DML. Le constructeur de valeurs de table peut être spécifié soit comme clause VALUES d'une instruction INSERT ... VALUES, soit comme table dérivée dans la clause USING de l'instruction MERGE ou la clause FROM."
@SteveC, @Sven - Merci beaucoup. Mais je pensais que VALUES
est utilisé uniquement avec Insert
déclaration. Et qu'est-ce que value(v)
- pourquoi je ne peux pas simplement écrire v
?
Il s'agit d'une ancienne réponse, qui ne fonctionne pas à tous les égards.
Ver https://stackoverflow.com/a/6871572/194653 qui a beaucoup plus de votes positifs et qui fonctionne avec sql server 2008+ et gère les valeurs nulles, etc.
Réponse originale mais problématique :
Eh bien, vous pouvez utiliser l'instruction CASE :
SELECT
CASE
WHEN Date1 >= Date2 AND Date1 >= Date3 THEN Date1
WHEN Date2 >= Date1 AND Date2 >= Date3 THEN Date2
WHEN Date3 >= Date1 AND Date3 >= Date2 THEN Date3
ELSE Date1
END AS MostRecentDate
Ne suffirait-il pas d'utiliser WHEN Date1 > Date2 AND Date1 > Date3 THEN Date1; WHEN Date2 > Date3 THEN Date3; ELSE Date3
?
C'est la réponse la plus évidente, mais elle ne fonctionne pas avec les valeurs NULL, et tenter de résoudre ce problème devient très compliqué.
Je fais un retour en arrière sur cet ancien message, mais vous pourriez intégrer chaque date dans un COALESCE pour gérer les NULL. L'une de ces instructions WHEN ressemblerait alors à ceci : WHEN Date1 >= COALESCE(Date2,'') AND Date1 >= COALESCE(Date3,'') THEN Date3 (faites de même pour les autres when)
C'est vrai, mais c'est quand même une réponse très utile car les gens trouvent cette question en référence à MySQL.
Il ne gère pas bien les NULL, mais si vous coalescez(col1, 0) autour des valeurs de vos colonnes, vous aurez du gaz voir cette réponse stackoverflow.com/questions/9831851/
Il existe 3 autres méthodes où UNPIVOT
(1) est de loin le plus rapide, suivi par le dépassement simulé (3) qui est beaucoup plus lent que (1) mais toujours plus rapide que (2).
CREATE TABLE dates
(
number INT PRIMARY KEY ,
date1 DATETIME ,
date2 DATETIME ,
date3 DATETIME ,
cost INT
)
INSERT INTO dates
VALUES ( 1, '1/1/2008', '2/4/2008', '3/1/2008', 10 )
INSERT INTO dates
VALUES ( 2, '1/2/2008', '2/3/2008', '3/3/2008', 20 )
INSERT INTO dates
VALUES ( 3, '1/3/2008', '2/2/2008', '3/2/2008', 30 )
INSERT INTO dates
VALUES ( 4, '1/4/2008', '2/1/2008', '3/4/2008', 40 )
GO
UNPIVOT
)SELECT number ,
MAX(dDate) maxDate ,
cost
FROM dates UNPIVOT ( dDate FOR nDate IN ( Date1, Date2,
Date3 ) ) as u
GROUP BY number ,
cost
GO
SELECT number ,
( SELECT MAX(dDate) maxDate
FROM ( SELECT d.date1 AS dDate
UNION
SELECT d.date2
UNION
SELECT d.date3
) a
) MaxDate ,
Cost
FROM dates d
GO
UNPIVOT
);WITH maxD
AS ( SELECT number ,
MAX(CASE rn
WHEN 1 THEN Date1
WHEN 2 THEN date2
ELSE date3
END) AS maxDate
FROM dates a
CROSS JOIN ( SELECT 1 AS rn
UNION
SELECT 2
UNION
SELECT 3
) b
GROUP BY Number
)
SELECT dates.number ,
maxD.maxDate ,
dates.cost
FROM dates
INNER JOIN MaxD ON dates.number = maxD.number
GO
DROP TABLE dates
GO
Savez-vous quelles sont les versions de SQL Server qui prennent en charge le pivotage/dépivrage ?
L'un ou l'autre des deux exemples ci-dessous fonctionnera :
SELECT MAX(date_columns) AS max_date
FROM ( (SELECT date1 AS date_columns
FROM data_table )
UNION
( SELECT date2 AS date_columns
FROM data_table
)
UNION
( SELECT date3 AS date_columns
FROM data_table
)
) AS date_query
Le second est un complément à de lassevk réponse.
SELECT MAX(MostRecentDate)
FROM ( SELECT CASE WHEN date1 >= date2
AND date1 >= date3 THEN date1
WHEN date2 >= date1
AND date2 >= date3 THEN date2
WHEN date3 >= date1
AND date3 >= date2 THEN date3
ELSE date1
END AS MostRecentDate
FROM data_table
) AS date_query
La première réponse est bonne, mais peut être considérablement simplifiée. La deuxième réponse ne fonctionne pas avec les valeurs NULL. Tenter de résoudre ce problème devient très compliqué.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.