sql >> Databasteknik >  >> NoSQL >> MongoDB

5 sätt att välja rader med minimivärdet för sin grupp i SQL

Här är fem alternativ för att använda SQL för att endast returnera de rader som har det lägsta värdet inom sin grupp.

Dessa exempel fungerar i de flesta större RDBMS, inklusive MySQL, MariaDB, Oracle, PostgreSQL, SQLite och SQL Server.

Exempeldata

Anta att vi har en tabell med följande data:

SELECT * FROM Gameshow;

Resultat:

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

Och anta att vi vill få lägst poäng för varje tävlande.

Alternativ 1

Ett snabbt och enkelt alternativ är att skapa en fråga med SQL GROUP BY klausul:

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

Resultat:

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

Alternativ 2

Om vi ​​vill inkludera spelet som varje tävlande spelade för att få lägsta poäng, är ett sätt att göra det att använda en korrelerad underfråga så här:

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

Resultat:

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

Korrelerade underfrågor hänvisar till en eller flera kolumner utanför underfrågan. Korrelerade underfrågor kan vara ineffektiva, främst på grund av att underfrågan exekveras upprepade gånger, en gång för varje rad som kan väljas av den yttre frågan. Korrelerade underfrågor kallas även upprepade underfrågor.

Alternativ 3

Vi kan alternativt använda en okorrelerad underfråga så här:

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;

Resultat:

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

Okorrelerade underfrågor är inte beroende av den yttre frågan för deras exekvering. De kan köras helt oberoende av den yttre frågan.

I Oracle måste vi ta bort AS när du deklarerar kolumnaliasen:

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;

Alternativ 4

Ett annat sätt att hämta rader med minimivärdet i en given kolumn är att använda en LEFT JOIN , så här:

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;

Resultat:

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

Alternativ 5

Ett annat sätt att göra det är att använda ett vanligt tabelluttryck med fönsterfunktion:

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;

Resultat:

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

  1. MongoDB NOW Aggregationsvariabel

  2. Mongodb infogar dokument utan _id-fält

  3. Hur såddar jag en mongodatabas med docker-compose?

  4. Vi introducerar Apache HBase Medium Object Storage (MOB) komprimeringspartitionsprinciper