Comment puis-je sélectionner des lignes avec MAX (valeur de colonne), DISTINCT par une autre colonne en SQL?

768

Ma table est:

id  home  datetime     player   resource
---|-----|------------|--------|---------
1  | 10  | 04/03/2009 | john   | 399 
2  | 11  | 04/03/2009 | juliet | 244
5  | 12  | 04/03/2009 | borat  | 555
3  | 10  | 03/03/2009 | john   | 300
4  | 11  | 03/03/2009 | juliet | 200
6  | 12  | 03/03/2009 | borat  | 500
7  | 13  | 24/12/2008 | borat  | 600
8  | 13  | 01/01/2009 | borat  | 700

J'ai besoin de sélectionner chaque homecontenant distinct la valeur maximale de datetime.

Le résultat serait:

id  home  datetime     player   resource 
---|-----|------------|--------|---------
1  | 10  | 04/03/2009 | john   | 399
2  | 11  | 04/03/2009 | juliet | 244
5  | 12  | 04/03/2009 | borat  | 555
8  | 13  | 01/01/2009 | borat  | 700

J'ai essayé:

-- 1 ..by the MySQL manual: 

SELECT DISTINCT
  home,
  id,
  datetime AS dt,
  player,
  resource
FROM topten t1
WHERE datetime = (SELECT
  MAX(t2.datetime)
FROM topten t2
GROUP BY home)
GROUP BY datetime
ORDER BY datetime DESC

Ça ne marche pas. L'ensemble de résultats contient 130 lignes, bien que la base de données en contienne 187. Le résultat inclut des doublons de home.

-- 2 ..join

SELECT
  s1.id,
  s1.home,
  s1.datetime,
  s1.player,
  s1.resource
FROM topten s1
JOIN (SELECT
  id,
  MAX(datetime) AS dt
FROM topten
GROUP BY id) AS s2
  ON s1.id = s2.id
ORDER BY datetime 

Nan. Donne tous les enregistrements.

-- 3 ..something exotic: 

Avec différents résultats.

Kaptah
la source

Réponses:

940

Tu es si proche! Tout ce que vous avez à faire est de sélectionner DEUX la maison et son heure de date maximale, puis de rejoindre la toptentable dans les DEUX champs:

SELECT tt.*
FROM topten tt
INNER JOIN
    (SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home) groupedtt 
ON tt.home = groupedtt.home 
AND tt.datetime = groupedtt.MaxDateTime
Michael La Voie
la source
5
Testez-le pour voir si deux datetime max égaux sont dans la même maison (avec des joueurs différents)
Maksym Gontar
5
Je pense que la manière classique de le faire est d'utiliser une jointure naturelle: "SELECT tt. * FROM topten tt NATURAL JOIN (SELECT home, MAX (datetime) AS datetime FROM topten GROUP BY home) mostrecent;" Même requête exactement, mais sans doute plus lisible
Parker
32
qu'en est-il s'il y a deux lignes qui ont les mêmes valeurs de champ 'home' et 'datetime'?
Kemal Duran
3
@Young le problème avec votre requête est qu'elle peut revenir id, playeret resourcede la ligne non max pour une maison donnée, c'est-à-dire pour la maison = 10, vous pouvez obtenir: 3 | 10 | 04/03/2009 | john | 300 En d'autres termes, cela ne garantit pas que toutes les colonnes d'une ligne du jeu de résultats appartiendront à max (datetime) pour une maison donnée.
sactiw
1
@ me1111 problème avec votre requête est qu'elle peut / peut ne pas retourner la ligne avec max (datetime) pour une maison donnée. La raison pour laquelle GROUP BY récupérera n'importe quelle ligne aléatoire pour chaque maison et ORDER BY
triera
87

La MySQLsolution la plus rapide , sans requêtes internes et sans GROUP BY:

SELECT m.*                    -- get the row that contains the max value
FROM topten m                 -- "m" from "max"
    LEFT JOIN topten b        -- "b" from "bigger"
        ON m.home = b.home    -- match "max" row with "bigger" row by `home`
        AND m.datetime < b.datetime           -- want "bigger" than "max"
WHERE b.datetime IS NULL      -- keep only if there is no bigger than max

Explication :

Rejoignez le tableau avec lui-même en utilisant la homecolonne. L'utilisation de LEFT JOINgarantit que toutes les lignes du tableau mapparaissent dans le jeu de résultats. Ceux qui n'ont pas de correspondance dans le tableau bauront NULLs pour les colonnes de b.

L'autre condition sur le JOINdemande de faire correspondre uniquement les lignes de bqui ont une plus grande valeur sur la datetimecolonne que la ligne de m.

En utilisant les données publiées dans la question, le LEFT JOINproduira ces paires:

+------------------------------------------+--------------------------------+
|              the row from `m`            |    the matching row from `b`   |
|------------------------------------------|--------------------------------|
| id  home  datetime     player   resource | id    home   datetime      ... |
|----|-----|------------|--------|---------|------|------|------------|-----|
| 1  | 10  | 04/03/2009 | john   | 399     | NULL | NULL | NULL       | ... | *
| 2  | 11  | 04/03/2009 | juliet | 244     | NULL | NULL | NULL       | ... | *
| 5  | 12  | 04/03/2009 | borat  | 555     | NULL | NULL | NULL       | ... | *
| 3  | 10  | 03/03/2009 | john   | 300     | 1    | 10   | 04/03/2009 | ... |
| 4  | 11  | 03/03/2009 | juliet | 200     | 2    | 11   | 04/03/2009 | ... |
| 6  | 12  | 03/03/2009 | borat  | 500     | 5    | 12   | 04/03/2009 | ... |
| 7  | 13  | 24/12/2008 | borat  | 600     | 8    | 13   | 01/01/2009 | ... |
| 8  | 13  | 01/01/2009 | borat  | 700     | NULL | NULL | NULL       | ... | *
+------------------------------------------+--------------------------------+

Enfin, la WHEREclause ne conserve que les paires qui ont NULLs dans les colonnes de b(elles sont marquées avec *dans le tableau ci-dessus); cela signifie qu'en raison de la deuxième condition de la JOINclause, la ligne sélectionnée ma la plus grande valeur dans la colonne datetime.

Lisez le livre SQL Antipatterns: Éviter les pièges de la programmation de base de données pour d'autres conseils SQL.

axiaque
la source
Avec SQLite, la première est beaucoup plus lente que la version de La Voie quand il n'y a pas d'index sur la colonne correspondante (ie "home"). (Testé avec 24k lignes résultant en 13k lignes)
Thomas Tempelmann
10
C'est la meilleure réponse, si vous montrez le plan d'exécution, vous verrez une étape de moins avec cette requête
TlmaK0
que se passera-t-il si 2 lignes ont le même homeet datetimeet datetimeest le maximum pour ce particulier home?
Istiaque Ahmed
Les deux lignes apparaissent dans le jeu de résultats. Cette réponse est une preuve de concept. Dans votre code réel, vous avez probablement un autre critère pour sélectionner un seul d'entre eux dans cette situation (peut-être le premier ou le dernier ou vous utilisez une autre colonne pour décider). Ajoutez simplement ce critère comme nouvelle condition dans la ONclause. Fe ... ON ... AND m.id < b.idpour conserver l'entrée la plus récente (celle avec la plus grande id) lorsque deux lignes ont les mêmes valeurs dans homeet datetimecolonnes et que c'est le maximum datetime.
axiac
Quels index optimiseraient le mieux pour une requête comme celle-ci?
AjaxLeung
73

Voici la version T-SQL :

-- Test data
DECLARE @TestTable TABLE (id INT, home INT, date DATETIME, 
  player VARCHAR(20), resource INT)
INSERT INTO @TestTable
SELECT 1, 10, '2009-03-04', 'john', 399 UNION
SELECT 2, 11, '2009-03-04', 'juliet', 244 UNION
SELECT 5, 12, '2009-03-04', 'borat', 555 UNION
SELECT 3, 10, '2009-03-03', 'john', 300 UNION
SELECT 4, 11, '2009-03-03', 'juliet', 200 UNION
SELECT 6, 12, '2009-03-03', 'borat', 500 UNION
SELECT 7, 13, '2008-12-24', 'borat', 600 UNION
SELECT 8, 13, '2009-01-01', 'borat', 700

-- Answer
SELECT id, home, date, player, resource 
FROM (SELECT id, home, date, player, resource, 
    RANK() OVER (PARTITION BY home ORDER BY date DESC) N
    FROM @TestTable
)M WHERE N = 1

-- and if you really want only home with max date
SELECT T.id, T.home, T.date, T.player, T.resource 
    FROM @TestTable T
INNER JOIN 
(   SELECT TI.id, TI.home, TI.date, 
        RANK() OVER (PARTITION BY TI.home ORDER BY TI.date) N
    FROM @TestTable TI
    WHERE TI.date IN (SELECT MAX(TM.date) FROM @TestTable TM)
)TJ ON TJ.N = 1 AND T.id = TJ.id

EDIT
Malheureusement, il n'y a pas de fonction RANK () OVER dans MySQL.
Mais il peut être émulé, voir Émulation de fonctions analytiques (classement AKA) avec MySQL .
Donc , c'est MySQL version:

SELECT id, home, date, player, resource 
FROM TestTable AS t1 
WHERE 
    (SELECT COUNT(*) 
            FROM TestTable AS t2 
            WHERE t2.home = t1.home AND t2.date > t1.date
    ) = 0
Maksym Gontar
la source
Désolé mec, # 1064 - Vous avez une erreur dans votre syntaxe SQL; consultez le manuel qui correspond à la version de votre serveur MySQL pour la bonne syntaxe à utiliser près de '() OVER (PARTITION BY krd ORDER BY daytime DESC) N FROM @rapsa) M WHERE N =' à la ligne 1
Kaptah
2
ah, vous utilisez donc MySQL. Voilà de quoi vous devriez partir! Je mettrai à jour la réponse bientôt.
Maksym Gontar
@MaxGontar, votre solution mysql est géniale, merci. que se passe-t-il si dans votre @_TestTable vous supprimez la ligne # 1>: SELECT 1, 10, '2009-03-04', 'john', 399, c'est-à-dire, si vous avez une seule ligne pour une valeur d'accueil donnée? THX.
egidiocs
2
BOGUE: remplacez "RANK ()" par "ROW_NUMBER ()". Si vous avez une égalité (causée par une valeur de date en double), vous aurez deux enregistrements avec "1" pour N.
MikeTeeVee
29

Cela fonctionnera même si vous avez deux lignes ou plus pour chacune homeavec des égales DATETIME:

SELECT id, home, datetime, player, resource
FROM   (
       SELECT (
              SELECT  id
              FROM    topten ti
              WHERE   ti.home = t1.home
              ORDER BY
                      ti.datetime DESC
              LIMIT 1
              ) lid
       FROM   (
              SELECT  DISTINCT home
              FROM    topten
              ) t1
       ) ro, topten t2
WHERE  t2.id = ro.lid
Quassnoi
la source
champ de couvercle ajouté dans le tableau, No Good
Kaptah
1
Celui-ci n'a pas été exécuté sur PHPMyAdmin. La page est actualisée mais il n'y a aucun résultat ni erreur ..?
Kaptah
WHERE ti.home = t1.home- pouvez-vous expliquer la syntaxe?
Istiaque Ahmed
@IstiaqueAhmed: qu'est-ce que vous ne comprenez pas exactement ici? Il s'agit d'une requête corrélée, et l'expression que vous mentionnez est une condition de corrélation.
Quassnoi
@Quassnoi, La selectrequête qui a la ligne WHERE ti.home = t1.home n'a pas besoin de la FROMclause qui définit t1. Alors, comment est-il utilisé?
Istiaque Ahmed
26

Je pense que cela vous donnera le résultat souhaité:

SELECT   home, MAX(datetime)
FROM     my_table
GROUP BY home

MAIS si vous avez également besoin d'autres colonnes, faites simplement une jointure avec la table d'origine (vérifiez la Michael La Voieréponse)

Meilleures salutations.

Ricardo Felgueiras
la source
8
Il a également besoin d'autres colonnes.
Quassnoi
4
id, home, datetime, player, resource
Quassnoi
17

Étant donné que les gens semblent continuer à courir dans ce fil (la date des commentaires varie de 1,5 an), ce n'est pas beaucoup plus simple:

SELECT * FROM (SELECT * FROM topten ORDER BY datetime DESC) tmp GROUP BY home

Aucune fonction d'agrégation nécessaire ...

À votre santé.

MJB
la source
6
Cela ne semble pas fonctionner. Message d'erreur: la colonne «x» n'est pas valide dans la liste de sélection car elle n'est contenue ni dans une fonction d'agrégation ni dans la clause GROUP BY.
Fowl
Cela ne fonctionnera certainement pas dans SQL Server ou Oracle, bien qu'il semble que cela puisse fonctionner dans MySQL.
ErikE
C'est vraiment magnifique! Comment cela marche-t-il? En utilisant DESC et la colonne de retour de groupe par défaut? Donc, si je l'ai changé en ASC datetime, il retournerait la première ligne pour chaque maison?
wayofthefuture
C'est génial!
Dog Lover
Ce droit ne fonctionne pas si vous avez des colonnes non agrégées (dans MySQL).
user3562927
11

Vous pouvez également essayer celui-ci et pour les grandes tables, les performances des requêtes seront meilleures. Cela fonctionne quand il n'y a pas plus de deux enregistrements pour chaque maison et que leurs dates sont différentes. Une meilleure requête générale MySQL est celle de Michael La Voie ci-dessus.

SELECT t1.id, t1.home, t1.date, t1.player, t1.resource
FROM   t_scores_1 t1 
INNER JOIN t_scores_1 t2
   ON t1.home = t2.home
WHERE t1.date > t2.date

Ou en cas de Postgres ou de ces dbs qui fournissent des fonctions analytiques, essayez

SELECT t.* FROM 
(SELECT t1.id, t1.home, t1.date, t1.player, t1.resource
  , row_number() over (partition by t1.home order by t1.date desc) rw
 FROM   topten t1 
 INNER JOIN topten t2
   ON t1.home = t2.home
 WHERE t1.date > t2.date 
) t
WHERE t.rw = 1
Shiva
la source
Cette réponse est-elle correcte? J'ai essayé de l'utiliser, mais il semble ne pas sélectionner l'enregistrement avec la date la plus récente pour 'home', mais ne supprime que l'enregistrement avec la date la plus ancienne. Voici un exemple: SQLfiddle
marcin93w
1
@kidOfDeath - Mise à jour de ma réponse avec contexte et requête Postgres
Shiva
Avec SQLite, la première est beaucoup plus lente que la version de La Voie quand il n'y a pas d'index sur la colonne correspondante (ie "home").
Thomas Tempelmann
8

Cela fonctionne sur Oracle:

with table_max as(
  select id
       , home
       , datetime
       , player
       , resource
       , max(home) over (partition by home) maxhome
    from table  
)
select id
     , home
     , datetime
     , player
     , resource
  from table_max
 where home = maxhome
FerranB
la source
1
comment cela choisit-il le datetime maximum? il a demandé de regrouper par domicile, et de sélectionner max datetime. Je ne vois pas comment cela fait ça.
n00b
8
SELECT  tt.*
FROM    TestTable tt 
INNER JOIN 
        (
        SELECT  coord, MAX(datetime) AS MaxDateTime 
        FROM    rapsa 
        GROUP BY
                krd 
        ) groupedtt
ON      tt.coord = groupedtt.coord
        AND tt.datetime = groupedtt.MaxDateTime
Kaptah
la source
8

Essayez ceci pour SQL Server:

WITH cte AS (
   SELECT home, MAX(year) AS year FROM Table1 GROUP BY home
)
SELECT * FROM Table1 a INNER JOIN cte ON a.home = cte.home AND a.year = cte.year
SysDragon
la source
5
SELECT c1, c2, c3, c4, c5 FROM table1 WHERE c3 = (select max(c3) from table)

SELECT * FROM table1 WHERE c3 = (select max(c3) from table1)
Jr.
la source
5

Voici la version de MySQL qui imprime une seule entrée où il y a des doublons MAX (datetime) dans un groupe.

Vous pouvez tester ici http://www.sqlfiddle.com/#!2/0a4ae/1

Exemples de données

mysql> SELECT * from topten;
+------+------+---------------------+--------+----------+
| id   | home | datetime            | player | resource |
+------+------+---------------------+--------+----------+
|    1 |   10 | 2009-04-03 00:00:00 | john   |      399 |
|    2 |   11 | 2009-04-03 00:00:00 | juliet |      244 |
|    3 |   10 | 2009-03-03 00:00:00 | john   |      300 |
|    4 |   11 | 2009-03-03 00:00:00 | juliet |      200 |
|    5 |   12 | 2009-04-03 00:00:00 | borat  |      555 |
|    6 |   12 | 2009-03-03 00:00:00 | borat  |      500 |
|    7 |   13 | 2008-12-24 00:00:00 | borat  |      600 |
|    8 |   13 | 2009-01-01 00:00:00 | borat  |      700 |
|    9 |   10 | 2009-04-03 00:00:00 | borat  |      700 |
|   10 |   11 | 2009-04-03 00:00:00 | borat  |      700 |
|   12 |   12 | 2009-04-03 00:00:00 | borat  |      700 |
+------+------+---------------------+--------+----------+

Version MySQL avec variable utilisateur

SELECT *
FROM (
    SELECT ord.*,
        IF (@prev_home = ord.home, 0, 1) AS is_first_appear,
        @prev_home := ord.home
    FROM (
        SELECT t1.id, t1.home, t1.player, t1.resource
        FROM topten t1
        INNER JOIN (
            SELECT home, MAX(datetime) AS mx_dt
            FROM topten
            GROUP BY home
          ) x ON t1.home = x.home AND t1.datetime = x.mx_dt
        ORDER BY home
    ) ord, (SELECT @prev_home := 0, @seq := 0) init
) y
WHERE is_first_appear = 1;
+------+------+--------+----------+-----------------+------------------------+
| id   | home | player | resource | is_first_appear | @prev_home := ord.home |
+------+------+--------+----------+-----------------+------------------------+
|    9 |   10 | borat  |      700 |               1 |                     10 |
|   10 |   11 | borat  |      700 |               1 |                     11 |
|   12 |   12 | borat  |      700 |               1 |                     12 |
|    8 |   13 | borat  |      700 |               1 |                     13 |
+------+------+--------+----------+-----------------+------------------------+
4 rows in set (0.00 sec)

Réponses acceptées

SELECT tt.*
FROM topten tt
INNER JOIN
    (
    SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home
) groupedtt ON tt.home = groupedtt.home AND tt.datetime = groupedtt.MaxDateTime
+------+------+---------------------+--------+----------+
| id   | home | datetime            | player | resource |
+------+------+---------------------+--------+----------+
|    1 |   10 | 2009-04-03 00:00:00 | john   |      399 |
|    2 |   11 | 2009-04-03 00:00:00 | juliet |      244 |
|    5 |   12 | 2009-04-03 00:00:00 | borat  |      555 |
|    8 |   13 | 2009-01-01 00:00:00 | borat  |      700 |
|    9 |   10 | 2009-04-03 00:00:00 | borat  |      700 |
|   10 |   11 | 2009-04-03 00:00:00 | borat  |      700 |
|   12 |   12 | 2009-04-03 00:00:00 | borat  |      700 |
+------+------+---------------------+--------+----------+
7 rows in set (0.00 sec)
Jason Heo
la source
Bien que j'aime cette réponse, car cela m'aide tellement, je dois signaler un défaut majeur, cela dépend du système mysql utilisé. Fondamentalement, cette solution repose sur la clause ORDER BY dans la sous-sélection. Cela POURRAIT, ou POURRAIT NE PAS fonctionner dans divers environnements mysql. Je ne l'ai pas essayé sur MySQL pur, mais c'est sûr que cela ne fonctionne PAS FIABLE sur MariaDB 10.1, comme expliqué ici stackoverflow.com/questions/26372511/… mais le même code fonctionne correctement sur Percona Server. Pour être précis, vous POURRIEZ, ou POURRAIT PAS obtenir les mêmes résultats, selon la quantité de colonnes t1.
Radek
L'exemple de cette déclaration est que, sur MariaDB 10.1, cela a fonctionné, lorsque j'ai utilisé 5 colonnes de la table t1. Dès que j'ai ajouté la sixième colonne, jouant visiblement avec le tri des données "naturelles" dans la table d'origine, cela a cessé de fonctionner. La raison en est que les données de la sous-sélection sont devenues non ordonnées et j'ai donc rencontré la condition "is_first_appear = 1" plusieurs fois. Le même code, avec les mêmes données, fonctionnait sur Percona ok.
Radek
5

Une autre façon de gt la ligne la plus récente par groupe en utilisant une sous-requête qui calcule essentiellement un classement pour chaque ligne par groupe, puis filtrez vos lignes les plus récentes comme avec rank = 1

select a.*
from topten a
where (
  select count(*)
  from topten b
  where a.home = b.home
  and a.`datetime` < b.`datetime`
) +1 = 1

DEMO

Voici la démo visuelle du rang no pour chaque ligne pour une meilleure compréhension

En lisant certains commentaires, qu'en est-il s'il y a deux lignes qui ont les mêmes valeurs de champ 'home' et 'datetime'?

La requête ci-dessus échouera et renverra plus de 1 lignes pour la situation ci-dessus. Pour couvrir cette situation, il faudra un autre critère / paramètre / colonne pour décider quelle ligne doit être prise et qui tombe dans la situation ci-dessus. En consultant l'échantillon de données, je suppose qu'il existe une colonne de clé primaire idqui doit être définie sur incrémentation automatique. Nous pouvons donc utiliser cette colonne pour choisir la ligne la plus récente en modifiant la même requête à l'aide d'une CASEinstruction comme

select a.*
from topten a
where (
  select count(*)
  from topten b
  where a.home = b.home
  and  case 
       when a.`datetime` = b.`datetime`
       then a.id < b.id
       else a.`datetime` < b.`datetime`
       end
) + 1 = 1

DEMO

La requête ci-dessus sélectionnera la ligne avec l'ID le plus élevé parmi les mêmes datetimevaleurs

démo visuelle pour le rang no pour chaque ligne

M Khalid Junaid
la source
2

Pourquoi ne pas utiliser: SELECT home, MAX (datetime) AS MaxDateTime, player, resource FROM topten GROUP BY home A-t-il manqué quelque chose?

Roland
la source
4
Cela ne serait valable qu'avec MySQL, et uniquement les versions avant 5.7 (?) Ou après 5.7 avec ONLY_FULL_GROUP_BY désactivé, car il s'agit de sélectionner des colonnes qui n'ont pas été agrégées / GROUPed (lecteur, ressource), ce qui signifie que MySQL fournira des valeurs choisies au hasard pour celles-ci. deux champs de résultat. Ce ne serait pas un problème pour la colonne de lecteur car cela correspond à la colonne d'accueil, mais la colonne de ressources ne serait pas en corrélation avec la colonne d'accueil ou datetime et vous ne pourriez pas garantir la valeur de ressource que vous recevriez.
simpleuser
+1 pour l'explication, MAIS par rapport à la question posée, cette requête ne retournera pas la expectedsortie dans MySQL version 5.6 beforeet je doute fortement qu'elle se comporte autrement dans MySQL version 5.7 et after.
sactiw
@simpleuser, `Ce ne serait pas un problème pour la colonne des joueurs car cela correspond à la colonne d'accueil` - pouvez-vous expliquer plus?
Istiaque Ahmed
@IstiaqueAhmed comme je le regarde à nouveau, cette déclaration est incorrecte. J'avais pensé que chaque joueur avait toujours la même valeur à la maison, mais je vois maintenant qu'ils ne le font pas, donc le même problème de sélection aléatoire se produira également pour cette colonne
simpleuser
1

Essaye ça

select * from mytable a join
(select home, max(datetime) datetime
from mytable
group by home) b
 on a.home = b.home and a.datetime = b.datetime

Cordialement K

Khb
la source
5
Testez-le pour distinct, si deux datetime max égaux sont dans la même maison (avec des joueurs différents)
Maksym Gontar
l'alias de max(datetime) is datetime. Cela ne posera-t-il aucun problème?
Istiaque Ahmed
Comment le plus élevé est-il datetimesélectionné?
Istiaque Ahmed
1

c'est la requête dont vous avez besoin:

 SELECT b.id, a.home,b.[datetime],b.player,a.resource FROM
 (SELECT home,MAX(resource) AS resource FROM tbl_1 GROUP BY home) AS a

 LEFT JOIN

 (SELECT id,home,[datetime],player,resource FROM tbl_1) AS b
 ON  a.resource = b.resource WHERE a.home =b.home;
Vijunav Vastivch
la source
pouvez-vous expliquer votre réponse?
Istiaque Ahmed
1

@Michae La réponse acceptée fonctionnera très bien dans la plupart des cas, mais elle échoue pour l'un comme ci-dessous.

Dans le cas où il y avait 2 lignes ayant HomeID et Datetime identiques, la requête retournera les deux lignes, pas HomeID différent comme requis, pour cela ajouter Distinct dans la requête comme ci-dessous.

SELECT DISTINCT tt.home  , tt.MaxDateTime
FROM topten tt
INNER JOIN
    (SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home) groupedtt 
ON tt.home = groupedtt.home 
AND tt.datetime = groupedtt.MaxDateTime
Manoj Kargeti
la source
résultat montre - "# 1054 - Colonne inconnue 'tt.MaxDateTime' dans 'liste de champs'"
Istiaque Ahmed
@IstiaqueAhmed avez-vous déposé MaxDatetime, c'est-à-dire un nom de colonne comme ça ..?
Manoj Kargeti
Non, la table dans OP n'a pas une telle colonne.
Istiaque Ahmed
l'erreur dit aussi la même chose, que voulez-vous faire exactement? pouvez-vous envoyer la structure de la table et votre requête.
Manoj Kargeti
1

J'espère que la requête ci-dessous donnera la sortie souhaitée:

Select id, home,datetime,player,resource, row_number() over (Partition by home ORDER by datetime desc) as rownum from tablename where rownum=1
Kiruba
la source