sql >> Databáze >  >> NoSQL >> MongoDB

5 způsobů, jak vybrat řádky s minimální hodnotou pro jejich skupinu v SQL

Zde je pět možností, jak pomocí SQL vrátit pouze ty řádky, které mají v rámci své skupiny minimální hodnotu.

Tyto příklady fungují ve většině hlavních RDBMS, včetně MySQL, MariaDB, Oracle, PostgreSQL, SQLite a SQL Server.

Ukázková data

Předpokládejme, že máme tabulku s následujícími údaji:

SELECT * FROM Gameshow;

Výsledek:

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

A předpokládejme, že chceme získat nejnižší skóre pro každého soutěžícího.

Možnost 1

Rychlá a snadná možnost je vytvořit dotaz pomocí SQL GROUP BY klauzule:

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

Výsledek:

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

Možnost 2

Pokud chceme zahrnout hru, kterou každý soutěžící hrál, aby získal minimální skóre, pak jedním ze způsobů, jak toho dosáhnout, je použít korelovaný dílčí dotaz, jako je tento:

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

Výsledek:

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

Korelované poddotazy odkazují na jeden nebo více sloupců mimo poddotaz. Korelované poddotazy mohou být neefektivní, hlavně kvůli skutečnosti, že poddotaz se provádí opakovaně, jednou pro každý řádek, který může být vybrán vnějším dotazem. Korelované poddotazy jsou také známé jako opakující se poddotazy.

Možnost 3

Alternativně můžeme použít nekorelovaný poddotaz takto:

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;

Výsledek:

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

Nekorelované poddotazy nezávisí na vnějším dotazu pro jejich provedení. Mohou se provádět zcela nezávisle na vnějším dotazu.

V Oracle musíme odstranit AS při deklaraci aliasů sloupců:

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;

Možnost 4

Dalším způsobem, jak načíst řádky s minimální hodnotou v daném sloupci, je použít LEFT JOIN , takto:

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;

Výsledek:

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

Možnost 5

Dalším způsobem, jak toho dosáhnout, je použití běžného tabulkového výrazu s funkcí okna:

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;

Výsledek:

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

  1. Odstranění konkrétních položek z pole pomocí MongoDB

  2. nelze se připojit k kontejneru redis z kontejneru aplikace

  3. Převést MongoDB BsonDocument na platný JSON v C#

  4. převod databáze z mysql na mongoDb