Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

SQL:Mengembalikan nilai paling umum untuk setiap orang

Komentar awal

Harap pelajari cara menggunakan notasi JOIN eksplisit, bukan notasi gabung implisit lama (sebelum 1992).

Gaya lama:

SELECT transactionTable.rating as MostCommonRating 
FROM personTable, transactionTable 
WHERE personTable.transactionid = transactionTable.transactionid 
AND personTable.personid = 1
GROUP BY transactionTable.rating 
ORDER BY COUNT(transactionTable.rating) desc 
LIMIT 1

Gaya yang disukai:

SELECT transactionTable.rating AS MostCommonRating 
  FROM personTable
  JOIN transactionTable 
    ON personTable.transactionid = transactionTable.transactionid 
 WHERE personTable.personid = 1
 GROUP BY transactionTable.rating 
 ORDER BY COUNT(transactionTable.rating) desc 
 LIMIT 1

Anda memerlukan kondisi AKTIF untuk setiap GABUNG.

Juga, personID nilai dalam data adalah string, bukan angka, jadi Anda harus menulis

 WHERE personTable.personid = "Ben"

misalnya, agar kueri berfungsi pada tabel yang ditampilkan.

Jawaban utama

Anda sedang mencari agregat dari sebuah agregat:dalam hal ini, jumlah maksimum. Jadi, solusi umum apa pun akan melibatkan MAX dan COUNT. Anda tidak dapat menerapkan MAX secara langsung ke COUNT, tetapi Anda dapat menerapkan MAX ke kolom dari sub-kueri yang kolomnya adalah COUNT.

Bangun kueri menggunakan Desain Kueri Berbasis Pengujian — TDQD.

Pilih orang dan peringkat transaksi

SELECT p.PersonID, t.Rating, t.TransactionID
  FROM PersonTable AS p
  JOIN TransactionTable AS t
    ON p.TransactionID = t.TransactionID

Pilih orang, peringkat, dan jumlah kemunculan peringkat

SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
  FROM PersonTable AS p
  JOIN TransactionTable AS t
    ON p.TransactionID = t.TransactionID
 GROUP BY p.PersonID, t.Rating

Hasil ini akan menjadi sub-kueri.

Temukan berapa kali seseorang mendapat peringkat

SELECT s.PersonID, MAX(s.RatingCount)
  FROM (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
          FROM PersonTable AS p
          JOIN TransactionTable AS t
            ON p.TransactionID = t.TransactionID
         GROUP BY p.PersonID, t.Rating
       ) AS s
 GROUP BY s.PersonID

Sekarang kita tahu berapa jumlah maksimum untuk setiap orang.

Hasil yang diperlukan

Untuk mendapatkan hasilnya, kita perlu memilih baris dari sub-query yang memiliki jumlah maksimum. Perhatikan bahwa jika seseorang memiliki 2 peringkat Baik dan 2 Buruk (dan 2 adalah jumlah maksimum peringkat dari jenis yang sama untuk orang tersebut), maka dua catatan akan ditampilkan untuk orang tersebut.

SELECT s.PersonID, s.Rating
  FROM (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
          FROM PersonTable AS p
          JOIN TransactionTable AS t
            ON p.TransactionID = t.TransactionID
         GROUP BY p.PersonID, t.Rating
       ) AS s
  JOIN (SELECT s.PersonID, MAX(s.RatingCount) AS MaxRatingCount
          FROM (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
                  FROM PersonTable AS p
                  JOIN TransactionTable AS t
                    ON p.TransactionID = t.TransactionID
                 GROUP BY p.PersonID, t.Rating
               ) AS s
         GROUP BY s.PersonID
       ) AS m
    ON s.PersonID = m.PersonID AND s.RatingCount = m.MaxRatingCount

Jika Anda ingin jumlah peringkat yang sebenarnya juga, itu mudah dipilih.

Itu bagian SQL yang cukup kompleks. Saya akan benci untuk mencoba menulis itu dari awal. Memang, saya mungkin tidak akan repot; Saya akan mengembangkannya selangkah demi selangkah, kurang lebih seperti yang ditunjukkan. Namun karena kami telah men-debug sub-kueri sebelum menggunakannya dalam ekspresi yang lebih besar, kami dapat yakin dengan jawabannya.

DENGAN klausa

Perhatikan bahwa SQL Standar menyediakan klausa WITH yang mengawali pernyataan SELECT, menamai sub-kueri. (Ini juga dapat digunakan untuk kueri rekursif, tetapi kami tidak membutuhkannya di sini.)

WITH RatingList AS
     (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
        FROM PersonTable AS p
        JOIN TransactionTable AS t
          ON p.TransactionID = t.TransactionID
       GROUP BY p.PersonID, t.Rating
     )
SELECT s.PersonID, s.Rating
  FROM RatingList AS s
  JOIN (SELECT s.PersonID, MAX(s.RatingCount) AS MaxRatingCount
          FROM RatingList AS s
         GROUP BY s.PersonID
       ) AS m
    ON s.PersonID = m.PersonID AND s.RatingCount = m.MaxRatingCount

Ini lebih sederhana untuk ditulis. Sayangnya, MySQL belum mendukung klausa WITH.

SQL di atas sekarang telah diuji terhadap IBM Informix Dynamic Server 11.70.FC2 yang berjalan di Mac OS X 10.7.4. Tes itu mengungkap masalah yang didiagnosis dalam komentar awal. SQL untuk jawaban utama bekerja dengan benar tanpa perlu diubah.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL menggabungkan hasil menjadi objek di codeigniter

  2. Bagaimana menghubungkan Django ke database MySQL melalui koneksi SSL?

  3. Cara Menghubungkan Ke Server MySQL Setelah Menginstal XAMPP Di Mac OS

  4. Bagaimana cara menyimpan nama file di database, dengan info lain saat mengunggah gambar ke server menggunakan PHP?

  5. Mengenkripsi Lalu Lintas MySQL Dalam Skrip