sql >> Database >  >> NoSQL >> MongoDB

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

Hier zijn vijf opties om SQL te gebruiken om alleen die rijen te retourneren die de minimale 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 laagste score willen halen.

Optie 1

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

SELECT 
    Contestant,
    MIN( Score ) AS MinScore
FROM Gameshow
GROUP BY Contestant
ORDER BY Contestant;

Resultaat:

+--------------+------------+
| Contestant   | MinScore   |
|--------------+------------|
| Faye         | 50         |
| Jet          | 31         |
| Spike        | 15         |
+--------------+------------+

Optie 2

Als we het spel willen opnemen dat elke deelnemer heeft gespeeld om de minimumscore te behalen, dan is een manier om dat te doen het gebruik van een gecorreleerde subquery zoals deze:

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

Resultaat:

+--------------+--------+---------+
| Contestant   | Game   | Score   |
|--------------+--------+---------|
| Faye         | 2      | 50      |
| Jet          | 1      | 31      |
| Spike        | 3      | 15      |
+--------------+--------+---------+

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, MIN( 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         | 2      | 50      |
| Jet          | 1      | 31      |
| Spike        | 3      | 15      |
+--------------+--------+---------+

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, MIN( 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 manier om rijen met de minimumwaarde in een bepaalde kolom op te halen, is door een LEFT JOIN te gebruiken. , 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         | 2      | 50      |
| Jet          | 1      | 31      |
| Spike        | 3      | 15      |
+--------------+--------+---------+

Optie 5

Een andere manier om dit te doen is door een algemene tabeluitdrukking met vensterfunctie te gebruiken:

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

Resultaat:

+--------------+--------+---------+
| Contestant   | Game   | Score   |
|--------------+--------+---------|
| Faye         | 2      | 50      |
| Jet          | 1      | 31      |
| Spike        | 3      | 15      |
+--------------+--------+---------+

  1. schemakenmerken ophalen van Mongoose Model

  2. MongoDB installeren op Ubuntu 16.04

  3. Moet ik voor elke verbinding een nieuwe Redis-client maken?

  4. wat zijn pagecache, dentries, inodes?