sql server 2008 - So erhalten Sie eine SQL-Zeile mit maximal einer Spalte und eine Gruppierung nach einer anderen Spalte

Translate

Ich muss Benutzer aus einer alten Datenbank auslesen, um sie für Statistiken in einem neuen System zu verwenden, aber ich habe nicht die ursprüngliche Benutzertabelle. Es gibt jedoch eine Statistiktabelle mit der Summe jedes Jahres, in der ich auch alle benötigten Benutzerinformationen finden kann. Außerdem gibt mir dies nur die Benutzer, die aktiv waren, was ich brauche.

Die Tabelle enthält die folgenden relevanten Spalten: (Die Statistikspalten sind hier nicht relevant.)

  • Benutzeridentifikation
  • Vorname
  • Familienname, Nachname
  • Email
  • Jahr

Ich möchte, dass die Benutzer-ID unterschiedlich ist, daher ist dies die einzige Spalte, die ich in GROUP BY haben kann. Ich werde MAX on Year ausführen, um die Werte des letzten Jahres zu erhalten. Vorname, Nachname und E-Mail müssen mit der Zeile übereinstimmen, in der MAX (Jahr) steht. Mit anderen Worten, die Leute haben im Laufe der Jahre möglicherweise sowohl Namen als auch E-Mails geändert, und ich möchte nur den letzten, da dies der einzige ist, der relevant ist.

Mein bester Vorschlag für eine SQL-Abfrage lautet wie folgt:

SELECT UserID, Firstname, LastName, Email, MAX(Year) AS Year
FROM myTable
GROUP BY UserID
ORDER BY LastName, FirstName

Das einzige Problem ist, dass ich mit SQL Server 2008 so etwas nicht machen kann, da alle Spalten entweder eine Funktion wie MAX oder einen Teil von GROUP BY haben müssen. Die Spalten Vorname, Nachname und E-Mail dürfen nicht unter GROUP BY stehen, da dadurch zu viele Datensätze erstellt werden. Es scheint irgendwie zu funktionieren, MAX auf alle zu setzen, aber dann kann ich nicht wissen, an welcher Spalte die MAX-Funktion tatsächlich arbeitet. Ich weiß nicht genau, ob es ein Problem sein wird, aber ich habe keine Zeit, 100 000 Zeilen zu durchsuchen, um festzustellen, ob tatsächlich ein Problem vorliegt.

Kurz gesagt, ich möchte die gesamte Zeile mit fünf Spalten, wobei MAX nur für eine Spalte und GROUP BY für eine andere Spalte funktioniert. Hat jemand eine gute Lösung oder ist es tatsächlich sicher, MAX für alle nicht gruppierten Zeilen zu verwenden?

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Ein paar Antworten ...


Korrelierte Unterabfrage ...

SELECT
  *
FROM
  myTable
WHERE
  Year = (SELECT MAX(Year) FROM myTable AS lookup WHERE lookup.UserID = myTable.UserID)


Join auf abgeleitetem Aggregat ...

SELECT
  *
FROM
  myTable
INNER JOIN
  (SELECT UserID, MAX(Year) AS Year FROM myTable GROUP BY UserID) AS lookup
    ON  lookup.UserID = myTable.UserID
    AND lookup.Year   = myTable.Year


Bestellter CTE mit ROW_NUMBER () ...

WITH
  sequenced_data AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY Year DESC) AS sequence_id,
    *
  FROM
    myTable
)
SELECT
  *
FROM
  sequenced_data
WHERE
  sequence_id = 1
Quelle
Translate

Haben Sie nur einen Jahresrekord pro Benutzer? Wenn ja, können Sie old'n'good join verwenden:

SELECT m.UserID, m.Firstname, m.LastName, m.Email, m.Year
FROM myTable m
    INNER JOIN (
        SELECT UserID, MAX(Year) as Year
        FROM myTable
        GROUP BY UserID
    ) x ON x.UserID=m.UserID and x.Year=m.Year
ORDER BY m.LastName, m.FirstName

Sicher können Sie Konstrukte aus neueren SQL-Versionen verwenden, ich habe mich gerade an ältere (= allgemeinere) Möglichkeiten gewöhnt :).

Quelle
Über den Autor