sql >> Database >  >> NoSQL >> MongoDB

5 manieren om rijen te selecteren met de maximale waarde voor hun groep in SQL

Hier zijn vijf opties om SQL te gebruiken om alleen die rijen te retourneren die de maximale waarde binnen hun groep hebben.

Deze voorbeelden werken in de meeste grote RDBMS'en, waaronder MySQL, MariaDB, Oracle, PostgreSQL, SQLite en SQL Server.

Voorbeeldgegevens

Stel dat we een tabel hebben met de volgende gegevens:

SELECT * FROM Gameshow;

Resultaat:

+--------------+--------+---------+
| Contestant   | Game   | Score   |
|--------------+--------+---------|
| Faye         | 1      | 85      |
| Faye         | 2      | 50      |
| Faye         | 3      | 63      |
| Jet          | 1      | 31      |
| Jet          | 2      | 40      |
| Jet          | 3      | 51      |
| Spike        | 1      | 25      |
| Spike        | 2      | 27      |
| Spike        | 3      | 15      |
+--------------+--------+---------+

En stel dat we voor elke deelnemer de hoogste score willen halen.

Optie 1

Een snelle en gemakkelijke optie is om een ​​query te maken met de SQL GROUP BY clausule:

SELECT 
    Contestant,
    MAX( Score ) AS MaxScore
FROM Gameshow
GROUP BY Contestant
ORDER BY Contestant;

Resultaat:

+--------------+------------+
| Contestant   | MaxScore   |
|--------------+------------|
| Faye         | 85         |
| Jet          | 51         |
| Spike        | 27         |
+--------------+------------+

Optie 2

Als we het spel willen opnemen dat elke deelnemer speelde om de maximale score te behalen, dan is een manier om dat te doen een gecorreleerde subquery zoals deze:

SELECT 
    Contestant,
    Game,
    Score
FROM Gameshow g1
WHERE Score = ( SELECT MAX( g2.Score )
              FROM Gameshow g2
              WHERE g1.Contestant = g2.Contestant )
ORDER BY Contestant;

Resultaat:

+--------------+--------+---------+
| Contestant   | Game   | Score   |
|--------------+--------+---------|
| Faye         | 1      | 85      |
| Jet          | 3      | 51      |
| Spike        | 2      | 27      |
+--------------+--------+---------+

Gecorreleerde subquery's verwijzen naar een of meer kolommen van buiten de subquery. Gecorreleerde subquery's kunnen inefficiënt zijn, voornamelijk vanwege het feit dat de subquery herhaaldelijk wordt uitgevoerd, één keer voor elke rij die door de buitenste query kan worden geselecteerd. Gecorreleerde subquery's worden ook wel herhalende subquery's genoemd.

Optie 3

We kunnen ook een niet-gecorreleerde subquery als deze gebruiken:

SELECT 
    g1.Contestant, 
    g1.Game,
    g1.Score
FROM Gameshow g1
JOIN (
  SELECT Contestant, MAX( Score ) AS Score
  FROM Gameshow
  GROUP BY Contestant ) AS g2
  ON g1.Contestant = g2.Contestant AND g1.Score = g2.Score
ORDER BY Contestant ASC;

Resultaat:

+--------------+--------+---------+
| Contestant   | Game   | Score   |
|--------------+--------+---------|
| Faye         | 1      | 85      |
| Jet          | 3      | 51      |
| Spike        | 2      | 27      |
+--------------+--------+---------+

Niet-gecorreleerde subquery's zijn niet afhankelijk van de buitenste query voor hun uitvoering. Ze kunnen volledig onafhankelijk van de buitenste query worden uitgevoerd.

In Oracle moeten we de AS . verwijderen bij het declareren van de kolomaliassen:

SELECT 
    g1.Contestant, 
    g1.Game,
    g1.Score
FROM Gameshow g1
JOIN (
  SELECT Contestant, MAX( Score ) Score
  FROM Gameshow
  GROUP BY Contestant ) g2
  ON g1.Contestant = g2.Contestant AND g1.Score = g2.Score
ORDER BY Contestant ASC;

Optie 4

Een andere optie is het gebruik van een LEFT JOIN , zoals dit:

SELECT 
    g1.Contestant, 
    g1.Game,
    g1.Score
FROM Gameshow g1
LEFT JOIN Gameshow g2 ON 
    g1.Contestant = g2.Contestant AND g1.Score < g2.Score
WHERE g2.Contestant IS NULL
ORDER BY g1.Contestant ASC;

Resultaat:

+--------------+--------+---------+
| Contestant   | Game   | Score   |
|--------------+--------+---------|
| Faye         | 1      | 85      |
| Jet          | 3      | 51      |
| Spike        | 2      | 27      |
+--------------+--------+---------+

Optie 5

Een andere manier om rijen met de maximale waarde in een bepaalde kolom op te halen, is door een algemene tabeluitdrukking met vensterfunctie te gebruiken:

WITH cte AS (
   SELECT Contestant, Game, Score,
            RANK() OVER ( PARTITION BY Contestant
            ORDER BY Score DESC
            ) AS r
    FROM Gameshow
)
SELECT Contestant, Game, Score
FROM cte
WHERE r = 1
ORDER BY Contestant ASC;

Resultaat:

+--------------+--------+---------+
| Contestant   | Game   | Score   |
|--------------+--------+---------|
| Faye         | 1      | 85      |
| Jet          | 3      | 51      |
| Spike        | 2      | 27      |
+--------------+--------+---------+

  1. In NodeJS, hoe resultaten van mongodb met verschillende veldnamen uit te voeren?

  2. MongoDB $project:eerdere pijplijnvelden behouden

  3. Hoe bereikt Redis de hoge doorvoer en prestaties?

  4. MongoDB $toBool