2008-10-31 6 views
4

select max(DELIVERY_TIMESTAMP) from DOCUMENTS; renverra l'heure à laquelle le dernier document a été remis. Comment puis-je retourner les autres colonnes pour le dernier document? Par exemple, je veux DOC_NAME pour le document le plus récent livré?La recherche SQL par MAX()

Je ne sais pas comment former la clause WHERE.

Répondre

6

Vous avez quelques options

SELECT DOC_NAME 
FROM DOCUMENTS 
WHERE DELIVERY_TIMESTAMP IN (
    SELECT MAX(DELIVERY_TIMESTAMP) 
    FROM DOCUMENTS 
) 

Ou avec joint

SELECT DOC_NAME 
FROM DOCUMENTS 
INNER JOIN (
    SELECT MAX(DELIVERY_TIMESTAMP) AS MAX_DELIVERY_TIMESTAMP 
    FROM DOCUMENTS 
) AS M 
    ON M.MAX_DELIVERY_TIMESTAMP = DOCUMENTS.DELIVERY_TIMESTAMP 

Il est plus compliqué s'il y a des doublons dans un horodatage ou vous avez besoin de plusieurs colonnes dans votre « max » critères (parce que MAX() est seulement sur la colonne pour toutes les lignes)

C'est là l'option JOIN est la seule option disponible, car une construction comme celui-ci ne sont pas disponibles (dire plusieurs commandes avec horodatage identique):

SELECT DOC_NAME 
FROM DOCUMENTS 
WHERE (DELIVERY_TIMESTAMP, ORDERID) IN (
    SELECT TOP 1 DELIVERY_TIMESTAMP, ORDERID 
    FROM DOCUMENTS 
    ORDER BY DELIVERY_TIMESTAMP DESC, ORDERID DESC 
) 

Si vous en fait, devez faire:

SELECT DOC_NAME 
FROM DOCUMENTS 
INNER JOIN (
    SELECT TOP 1 DELIVERY_TIMESTAMP, ORDERID 
    FROM DOCUMENTS 
    ORDER BY DELIVERY_TIMESTAMP DESC, ORDERID DESC 
) AS M 
    ON M.DELIVERY_TIMESTAMP = DOCUMENTS.DELIVERY_TIMESTAMP 
     AND M.ORDERID = DOCUMENTS.ORDERID 
+1

Cade, j'allais répondre avec la solution JOIN, puis j'ai inspecté le plan d'exécution pour chaque technique. Sql Server 2005 (le DB que j'ai à portée de main) utilise le même plan d'exécution pour chaque syntaxe. Donc Paul, vous avez le choix entre ... et les performances ne souffriront pas –

+0

Oui, l'optimiseur dans SQL Server est très bon. Je vais modifier ma réponse pour noter que la solution JOIN est la seule qui fonctionne quand vous avez un tuple MAX. –

+0

Merci beaucoup! –

1
Select Max(DELIVERY_TIMESTAMP), 
     Doc_Name 
From TableName 
Group By Doc_Name 

Cela devrait le faire, sauf si j'ai manqué quelque chose dans la question.

+0

Je ne connais aucune variante SQL où cela fonctionne, et au moins sur Oracle, ce n'est pas le cas. – Alnitak

+0

Cela fonctionne uniquement si vous commandez BY MAX (DELIVERY_TIMESTAMP) et prenez TOP 1. –

4
SELECT 
    DELIVERY_TIMESTAMP, 
    OTHER_COLUMN 
FROM 
    DOCUMENTS 
WHERE 
    DELIVERY_TIMESTAMP = (SELECT MAX(DELIVERY_TIMESTAMP) FROM DOCUMENTS) 
+0

C'est mieux que le mien, je vote pour le vôtre. –

2

En MSSQL, ce qui suit fonctionne aussi:

SELECT TOP 1 * FROM DOCUMENTS ORDER BY DELIVERY_TIMESTAMP DESC 
2

Sur certaines versions de SQL (c.-à- MySQL) vous pouvez faire ceci:

SELECT * 
FROM DOCUMENTS 
ORDER BY DELIVERY_TIMESTAMP DESC 
LIMIT 1 
+0

Ceci retourne tous les documents. Je ne veux que le document le plus récent. –

+0

@Paul: La requête a la clause "LIMIT". Il ne renverra jamais plus d'un enregistrement. L'enregistrement renvoyé est celui avec la valeur maximale pour 'DELIVERY_TIMESTAMP' (le document récent que vous voulez) –