Wie kann ich Zeilen mit MAX (Spaltenwert), DISTINCT durch eine andere Spalte in SQL AUSWÄHLEN?

768

Mein Tisch ist:

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

Ich muss jedes einzelne auswählen home, das den Maximalwert von enthält datetime.

Ergebnis wäre:

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

Ich habe versucht:

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

Funktioniert nicht Die Ergebnismenge enthält 130 Zeilen, obwohl die Datenbank 187 enthält home. Das Ergebnis enthält einige Duplikate von .

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

Nee. Gibt alle Aufzeichnungen.

-- 3 ..something exotic: 

Mit verschiedenen Ergebnissen.

Kaptah
quelle

Antworten:

939

Du bist so nah! Alles, was Sie tun müssen, ist, sowohl das Haus als auch die maximale Datumszeit auszuwählen und sich dann wieder mit der toptenTabelle in BEIDEN Feldern zu verbinden:

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
quelle
5
Testen Sie es auf unterschiedliche, wenn zwei gleiche maximale Datumszeit im selben Haus sind (mit unterschiedlichen Spielern)
Maksym Gontar
5
Ich denke, der klassische Weg, dies zu tun, ist mit einem natürlichen Join: "SELECT tt. * FROM topten tt NATURAL JOIN (SELECT home, MAX (datetime) AS datetime FROM topten GROUP BY home) am häufigsten;" Gleiche Abfrage genau, aber wohl besser lesbar
Parker
32
Was ist, wenn es zwei Zeilen gibt, die dieselben Feldwerte für "home" und "datetime" haben?
Kemal Duran
3
@Young das Problem mit Ihrer Anfrage ist , dass sie zurückkehren können id, playerund resourcevon nicht-max Zeile für ein Haus für Haus dh gegeben 10 = Sie bekommen können: 3 | 10 | 04/03/2009 | john | 300 Mit anderen Worten ist es garantiert nicht , dass alle Spalte einer Zeile in resultset gehören wird bis max (datetime) für gegebenes Zuhause.
Sactiw
1
@ me1111 Problem mit Ihrer Abfrage ist, dass sie möglicherweise die Zeile ith max (datetime) für ein bestimmtes Haus zurückgibt / nicht zurückgibt. Der Grund dafür ist, dass GROUP BY eine beliebige zufällige Zeile für jedes Haus
abruft
87

Die schnellste MySQLLösung, ohne innere Fragen und ohne 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

Erklärung :

Verbinden Sie die Tabelle mit sich selbst mithilfe der homeSpalte. Durch die Verwendung von wird LEFT JOINsichergestellt, dass alle Zeilen aus der Tabelle min der Ergebnismenge angezeigt werden. Diejenigen, die keine Übereinstimmung in der Tabelle bhaben, haben NULLs für die Spalten von b.

Die andere Bedingung in der JOINAufforderung, nur den Zeilen zuzuordnen b, die einen größeren Wert in der datetimeSpalte haben als die Zeile aus m.

Unter Verwendung der in der Frage angegebenen Daten LEFT JOINwerden die folgenden Paare erzeugt:

+------------------------------------------+--------------------------------+
|              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       | ... | *
+------------------------------------------+--------------------------------+

Schließlich enthält die WHEREKlausel nur die Paare, die NULLs in den Spalten von haben b(sie sind *in der obigen Tabelle mit gekennzeichnet ). Dies bedeutet, dass aufgrund der zweiten Bedingung aus der JOINKlausel die ausgewählte Zeile mden größten Wert in der Spalte hat datetime.

Lesen Sie die SQL - Antipatterns: Die Vermeidung der Gefahren von Datenbankprogrammierung Buch für andere SQL - Tipps.

Axiac
quelle
Mit SQLiteist die erste viel langsamer als die Version von La Voie, wenn es keinen Index für die übereinstimmende Spalte gibt (dh "home"). (Getestet mit 24k Reihen, was 13k Reihen ergibt)
Thomas Tempelmann
10
Dies ist die beste Antwort. Wenn Sie den Ausführungsplan
anzeigen,
was passiert , wenn zwei Reihen das gleiche haben homeund datetimeund das datetimeist das Maximum für diesen bestimmt home?
Istiaque Ahmed
Beide Zeilen werden in der Ergebnismenge angezeigt. Diese Antwort ist ein Proof of Concept. In Ihrem realen Code haben Sie wahrscheinlich ein anderes Kriterium, um in dieser Situation nur eines davon auszuwählen (möglicherweise das erste oder das letzte oder Sie verwenden eine andere Spalte, um zu entscheiden). Fügen Sie dieses Kriterium einfach als neue Bedingung in die ONKlausel ein. Fe ... ON ... AND m.id < b.id, um den neuesten Eintrag (den mit dem größten id) beizubehalten, wenn zwei Zeilen dieselben Werte in homeund datetimeSpalten haben und dies das Maximum ist datetime.
Axiac
Welche Indizes lassen sich für eine solche Abfrage am besten optimieren?
AjaxLeung
73

Hier geht T-SQL- Version:

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

BEARBEITEN
Leider gibt es in MySQL keine RANK () OVER-Funktion.
Es kann jedoch emuliert werden, siehe Emulieren von Analysefunktionen (AKA-Ranking) mit MySQL .
Das ist also die 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
quelle
Entschuldigung, # 1064 - Sie haben einen Fehler in Ihrer SQL-Syntax. Überprüfen Sie das Handbuch, das Ihrer MySQL-Serverversion entspricht, auf die richtige Syntax für die Verwendung in der Nähe von '() OVER (PARTITION BY krd ORDER BY daytime DESC) N FROM @rapsa) M WHERE N =' in Zeile 1
Kaptah
2
Ah, Sie verwenden also MySQL. Davon sollten Sie ausgehen! Ich werde die Antwort bald aktualisieren.
Maksym Gontar
@ MaxGontar, deine MySQL-Lösung rockt, danke. Was ist, wenn Sie in Ihrer @_TestTable Zeile 1 entfernen>: SELECT 1, 10, '2009-03-04', 'John', 399, was ist, wenn Sie eine einzelne Zeile für einen bestimmten Home-Wert haben? Danke.
Egidiocs
2
BUG: Ersetzen Sie "RANK ()" durch "ROW_NUMBER ()". Wenn Sie ein Unentschieden haben (verursacht durch einen doppelten Datumswert), haben Sie zwei Datensätze mit "1" für N.
MikeTeeVee
29

Dies funktioniert auch dann, wenn Sie zwei oder mehr Zeilen mit jeweils homegleichen Zeilen haben 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
quelle
Deckelfeld
1
Dieser wurde nicht auf PHPMyAdmin ausgeführt. Seite aktualisiert, aber es gibt kein Ergebnis oder Fehler ..?
Kaptah
WHERE ti.home = t1.home- Können Sie die Syntax erklären?
Istiaque Ahmed
@IstiaqueAhmed: Was genau verstehst du hier nicht? Es ist eine korrelierte Abfrage, und der von Ihnen erwähnte Ausdruck ist eine Korrelationsbedingung.
Quassnoi
@Quassnoi, Die selectAbfrage mit der Zeile WHERE ti.home = t1.home benötigt nicht die FROMdefinierte Klausel t1. Wie wird es verwendet?
Istiaque Ahmed
26

Ich denke, dies wird Ihnen das gewünschte Ergebnis bringen:

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

ABER wenn Sie auch andere Spalten benötigen, stellen Sie einfach eine Verknüpfung mit der Originaltabelle her ( Michael La VoieAntwort überprüfen )

Freundliche Grüße.

Ricardo Felgueiras
quelle
8
Er braucht auch andere Spalten.
Quassnoi
4
ID, Heimat, Datum / Uhrzeit, Spieler, Ressource
Quassnoi
17

Da die Leute immer wieder auf diesen Thread stoßen (das Kommentardatum liegt zwischen 1,5 Jahren), ist das nicht viel einfacher:

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

Keine Aggregationsfunktionen erforderlich ...

Prost.

MJB
quelle
6
Das scheint nicht zu funktionieren. Fehlermeldung: Die Spalte 'x' ist in der Auswahlliste ungültig, da sie weder in einer Aggregatfunktion noch in der GROUP BY-Klausel enthalten ist.
Geflügel
Dies funktioniert definitiv nicht in SQL Server oder Oracle, obwohl es so aussieht, als würde es in MySQL funktionieren.
ErikE
Das ist wirklich schön! Wie funktioniert das? Durch Verwendung von DESC und der Standard-Gruppenrückgabespalte? Wenn ich es also in datetime ASC ändern würde, würde es die früheste Zeile für jedes Haus zurückgeben?
Wayofthefuture
Das ist brilliant!
Hundeliebhaber
Diese Anweisung funktioniert nicht, wenn Sie nicht aggregierte Spalten haben (in MySQL).
Benutzer3562927
11

Sie können dies auch versuchen und bei großen Tabellen ist die Abfrageleistung besser. Es funktioniert, wenn nicht mehr als zwei Datensätze für jedes Haus vorhanden sind und die Daten unterschiedlich sind. Eine bessere allgemeine MySQL-Abfrage stammt von Michael La Voie oben.

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

Oder versuchen Sie es bei Postgres oder solchen Datenbankanbietern, die Analysefunktionen bereitstellen

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
quelle
Ist diese Antwort richtig? Ich habe versucht, es zu verwenden, aber es scheint nicht den Datensatz mit dem neuesten Datum für "Zuhause" auszuwählen, sondern nur den Datensatz mit dem ältesten Datum zu entfernen. Hier ist ein Beispiel: SQLfiddle
marcin93w
1
@kidOfDeath - Aktualisiert meine Antwort mit Kontext und Postgres-Abfrage
Shiva
Mit SQLiteist die erste viel langsamer als die Version von La Voie, wenn es keinen Index für die übereinstimmende Spalte gibt (dh "home").
Thomas Tempelmann
8

Dies funktioniert unter 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
quelle
1
Wie wählt dies die maximale Datums- und Uhrzeitangabe aus? Er bat darum, nach Hause zu gruppieren und die maximale Datumszeit auszuwählen. Ich sehe nicht, wie das das macht.
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
quelle
8

Versuchen Sie dies für 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
quelle
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.
quelle
5

Hier ist die MySQL-Version, die nur einen Eintrag druckt, in dem Duplikate MAX (datetime) in einer Gruppe vorhanden sind.

Sie können hier http://www.sqlfiddle.com/#!2/0a4ae/1 testen

Beispieldaten

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 |
+------+------+---------------------+--------+----------+

MySQL-Version mit Benutzervariable

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)

Akzeptierte Antworten

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
quelle
Obwohl ich diese Antwort liebe, da sie mir so sehr hilft, muss ich auf einen großen Fehler hinweisen, der vom verwendeten MySQL-System abhängt. Grundsätzlich basiert diese Lösung auf der ORDER BY-Klausel in subselect. Dies könnte oder könnte nicht in verschiedenen MySQL-Umgebungen funktionieren. Ich habe es nicht mit reinem MySQL versucht, aber sicher funktioniert dies unter MariaDB 10.1 nicht ZUVERLÄSSIG, wie hier erläutert. Stackoverflow.com/questions/26372511/… aber derselbe Code funktioniert auf Percona Server einwandfrei. Um genau zu sein, KÖNNEN Sie oder KÖNNEN NICHT die gleichen Ergebnisse erzielen, abhängig von der Anzahl der t1-Spalten.
Radek
Das Beispiel für diese Anweisung ist, dass es in MariaDB 10.1 funktioniert hat, als ich 5 Spalten aus der Tabelle t1 verwendet habe. Sobald ich die sechste Spalte hinzugefügt hatte, die offensichtlich mit der "natürlichen" Datensortierung in der Originaltabelle zu tun hatte, funktionierte sie nicht mehr. Der Grund ist, dass die Daten in der Unterauswahl ungeordnet wurden und ich daher die Bedingung "is_first_appear = 1" mehrmals erfüllt hatte. Der gleiche Code mit den gleichen Daten funktionierte auf Percona ok.
Radek
5

Eine andere Möglichkeit, die letzte Zeile pro Gruppe mithilfe einer Unterabfrage zu ermitteln, die im Grunde genommen einen Rang für jede Zeile pro Gruppe berechnet und dann Ihre neuesten Zeilen wie mit Rang = 1 herausfiltert

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

DEMO

Hier ist die visuelle Demo für Rang Nr. Für jede Zeile zum besseren Verständnis

Wenn Sie einige Kommentare lesen, was ist, wenn es zwei Zeilen gibt, die dieselben Feldwerte für 'home' und 'datetime' haben?

Die obige Abfrage schlägt fehl und gibt für die obige Situation mehr als 1 Zeilen zurück. Um diese Situation zu vertuschen, müssen andere Kriterien / Parameter / Spalten verwendet werden, um zu entscheiden, welche Zeile in die obige Situation fallen soll. Beim Anzeigen des Beispieldatensatzes gehe ich davon aus, dass es eine Primärschlüsselspalte gibt id, die auf automatische Inkrementierung eingestellt werden sollte. Wir können diese Spalte also verwenden, um die neueste Zeile auszuwählen, indem wir dieselbe Abfrage mit Hilfe einer CASEAnweisung wie optimieren

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

Die obige Abfrage wählt die Zeile mit der höchsten ID unter denselben datetimeWerten aus

visuelle Demo für Rang Nr. für jede Zeile

M Khalid Junaid
quelle
2

Warum nicht verwenden: SELECT home, MAX (datetime) AS MaxDateTime, Player, Ressource FROM topten GROUP BY home Habe ich etwas verpasst?

Roland
quelle
4
Dies gilt nur für MySQL und nur für Versionen vor 5.7 (?) Oder nach 5.7 mit deaktiviertem ONLY_FULL_GROUP_BY, da Spalten ausgewählt werden, die nicht aggregiert / gruppiert wurden (Player, Ressource), was bedeutet, dass MySQL zufällig ausgewählte Werte für diese bereitstellt zwei Ergebnisfelder. Für die Player-Spalte wäre dies kein Problem, da dies mit der Home-Spalte korreliert, die Ressourcenspalte jedoch nicht mit der Home- oder Datetime-Spalte korreliert und Sie nicht garantieren können, welchen Ressourcenwert Sie erhalten würden.
simpleuser
+1 für die Erklärung, ABER bei der gestellten Frage gibt diese Abfrage die expectedAusgabe in MySQL Version 5.6 nicht zurück beforeund ich bezweifle sehr, dass sie sich in MySQL Version 5.7 und anders verhält after.
Sactiw
@simpleuser, "Es wäre kein Problem für die Spielerspalte, da dies mit der Home-Spalte korreliert" - können Sie mehr erklären?
Istiaque Ahmed
@IstiaqueAhmed, wenn ich es mir noch einmal ansehe, ist diese Aussage falsch. Ich hatte gedacht, dass jeder Spieler immer den gleichen Heimwert hat, aber ich sehe jetzt, dass dies nicht der
Fall ist
1

Versuche dies

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

Grüße K.

Khb
quelle
5
Testen Sie es auf unterschiedliche, wenn zwei gleiche maximale Datenzeit im selben Haus sind (mit unterschiedlichen Spielern)
Maksym Gontar
Der Alias ​​für max(datetime) ist datetime. Wird es kein Problem machen?
Istiaque Ahmed
Wie wird der Höchste datetimeausgewählt?
Istiaque Ahmed
1

Dies ist die Abfrage, die Sie benötigen:

 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
quelle
Kannst du deine Antwort erklären?
Istiaque Ahmed
1

@Michae Die akzeptierte Antwort funktioniert in den meisten Fällen einwandfrei, schlägt jedoch für eine der folgenden fehl.

Falls zwei Zeilen mit der gleichen HomeID und Datetime vorhanden sind, gibt die Abfrage beide Zeilen zurück, nicht die erforderliche HomeID, um Distinct in der Abfrage wie folgt hinzuzufügen.

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
quelle
Ergebnis zeigt - "# 1054 - Unbekannte Spalte 'tt.MaxDateTime' in '
Feldliste
@IstiaqueAhmed Haben Sie MaxDatetime abgelegt, dh einen solchen Spaltennamen?
Manoj Kargeti
Nein, die Tabelle in OP enthält keine solche Spalte.
Istiaque Ahmed
der Fehler sagt auch das gleiche bitte ... was genau willst du tun? Kannst du die Tabellenstruktur und deine Anfrage senden?
Manoj Kargeti
1

Hoffe, dass die folgende Abfrage die gewünschte Ausgabe liefert:

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