MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

5 sposobów na wybranie wierszy o maksymalnej wartości dla ich grupy w SQL

Oto pięć opcji użycia SQL do zwrócenia tylko tych wierszy, które mają maksymalną wartość w swojej grupie.

Te przykłady działają w większości głównych RDBMS, w tym MySQL, MariaDB, Oracle, PostgreSQL, SQLite i SQL Server.

Przykładowe dane

Załóżmy, że mamy tabelę z następującymi danymi:

SELECT * FROM Gameshow;

Wynik:

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

I załóżmy, że chcemy uzyskać najwyższy wynik dla każdego uczestnika.

Opcja 1

Szybkim i łatwym rozwiązaniem jest skonstruowanie zapytania za pomocą SQL GROUP BY klauzula:

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

Wynik:

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

Opcja 2

Jeśli chcemy uwzględnić grę, w którą grał każdy zawodnik, aby uzyskać maksymalny wynik, jednym ze sposobów na to jest użycie skorelowanego podzapytania w ten sposób:

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

Wynik:

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

Skorelowane podzapytania odwołują się do co najmniej jednej kolumny spoza podzapytania. Skorelowane podzapytania mogą być nieefektywne, głównie ze względu na fakt, że podzapytanie jest wykonywane wielokrotnie, raz dla każdego wiersza, który może zostać wybrany przez zapytanie zewnętrzne. Skorelowane podzapytania są również nazywane podzapytaniami powtarzającymi się.

Opcja 3

Alternatywnie możemy użyć nieskorelowanego podzapytania w ten sposób:

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;

Wynik:

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

Nieskorelowane podzapytania nie zależą od zewnętrznego zapytania do ich wykonania. Mogą działać całkowicie niezależnie od zewnętrznego zapytania.

W Oracle musimy usunąć AS podczas deklarowania aliasów kolumn:

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;

Opcja 4

Inną opcją jest użycie LEFT JOIN , tak:

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;

Wynik:

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

Opcja 5

Innym sposobem na pobranie wierszy z maksymalną wartością w danej kolumnie jest użycie wspólnego wyrażenia tabelowego z funkcją okna:

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;

Wynik:

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

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Wstaw MongoDB()

  2. Globalnie używaj JsonConverter w klasie bez atrybutu

  3. Unikaj łącznego limitu 16 MB

  4. Mongorestore, od serwera produkcyjnego meteor do lokalnego

  5. mongoimport wybór typu pola