MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

5 Cara Memilih Baris dengan Nilai Maksimum untuk Grupnya di SQL

Berikut adalah lima opsi untuk menggunakan SQL untuk mengembalikan hanya baris yang memiliki nilai maksimum dalam grupnya.

Contoh-contoh ini berfungsi di sebagian besar RDBMS utama, termasuk MySQL, MariaDB, Oracle, PostgreSQL, SQLite, dan SQL Server.

Contoh Data

Misalkan kita memiliki tabel dengan data berikut:

SELECT * FROM Gameshow;

Hasil:

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

Dan misalkan kita ingin mendapatkan nilai tertinggi untuk setiap kontestan.

Opsi 1

Opsi cepat dan mudah adalah membuat kueri dengan SQL GROUP BY klausa:

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

Hasil:

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

Opsi 2

Jika kita ingin memasukkan game yang dimainkan setiap kontestan untuk mendapatkan skor maksimal, maka salah satu caranya adalah dengan menggunakan subquery berkorelasi seperti ini:

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

Hasil:

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

Subquery berkorelasi mengacu pada satu atau lebih kolom dari luar subquery. Subquery yang berkorelasi dapat menjadi tidak efisien, terutama karena fakta bahwa subquery dieksekusi berulang kali, sekali untuk setiap baris yang mungkin dipilih oleh kueri luar. Subquery berkorelasi juga dikenal sebagai subquery berulang.

Opsi 3

Sebagai alternatif, kita dapat menggunakan subquery yang tidak berkorelasi seperti ini:

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;

Hasil:

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

Subkueri yang tidak berkorelasi tidak bergantung pada kueri luar untuk eksekusinya. Mereka dapat mengeksekusi sepenuhnya secara independen dari kueri luar.

Di Oracle, kita perlu menghapus AS saat mendeklarasikan alias kolom:

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;

Opsi 4

Pilihan lainnya adalah menggunakan LEFT JOIN , seperti ini:

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;

Hasil:

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

Opsi 5

Cara lain untuk mengambil baris dengan nilai maksimum dalam kolom tertentu adalah dengan menggunakan ekspresi tabel umum dengan fungsi jendela:

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;

Hasil:

+--------------+--------+---------+
| 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. mgo - kinerja kueri tampaknya lambat secara konsisten (500-650 ms)

  2. Mengapa skema saya tidak menambahkan nilai default dalam array luwak?

  3. Gunakan server MongoDB tiruan untuk pengujian unit

  4. Agregasi MongoDb:Bagaimana saya bisa mengelompokkan array-1 berdasarkan array-2 lain ketika diberikan array-1 dan array-2?

  5. Apakah ada opsi untuk membatasi penggunaan memori mongodb?