PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Temukan film dengan jumlah penghargaan tertinggi di tahun tertentu - duplikasi kode

Anda dapat menggunakan ekspresi tabel umum untuk menghindari duplikasi kode:

with cte_s as (
   select id_movie, count(id_movie) as awards
   from Award natural join awardwinner 
   where award_year = 2012
   group by id_movie
)
select
    sub.id_movie, sub.awards
from cte_s as sub
where sub.awards = (select max(sub2.awards) from cte_s as sub2)

atau Anda dapat melakukan sesuatu seperti ini dengan fungsi jendela (belum diuji, tapi saya pikir PostgreSQL mengizinkan ini):

with cte_s as (
    select
        id_movie,
        count(id_movie) as awards,
        max(count(id_movie)) over() as max_awards
    from Award natural join awardwinner 
    where award_year = 2012
    group by id_movie
)
select id_movie
from cte_s
where max_awards = awards

Cara lain untuk melakukannya adalah dengan menggunakan rank() fungsi (belum diuji, mungkin Anda harus menggunakan dua cte alih-alih satu):

with cte_s as (
    select
        id_movie,
        count(id_movie) as awards,
        rank() over(order by count(id_movie) desc) as rnk
    from Award natural join awardwinner 
    where award_year = 2012
    group by id_movie
)
select id_movie
from cte_s
where rnk = 1

perbarui Ketika saya membuat jawaban ini, tujuan utama saya adalah menunjukkan cara menggunakan cte untuk menghindari duplikasi kode. Secara umum, lebih baik menghindari penggunaan cte lebih dari satu kali dalam kueri jika memungkinkan - kueri pertama menggunakan 2 pemindaian tabel (atau pencarian indeks) dan kedua dan ketiga hanya menggunakan satu, jadi saya harus menentukan bahwa itu lebih baik untuk digunakan pertanyaan-pertanyaan ini. Bagaimanapun, @Erwin membuat tes ini dalam jawabannya. Hanya untuk menambah poin utamanya yang hebat:

  • Saya juga menyarankan agar tidak natural join karena sifat rawan kesalahan ini. Sebenarnya RDBMS utama saya adalah SQL Server yang tidak mendukungnya jadi saya lebih terbiasa dengan outer/inner join eksplisit .
  • Adalah kebiasaan yang baik untuk selalu menggunakan alias dalam kueri Anda, sehingga Anda dapat menghindari hasil aneh .
  • Ini bisa menjadi hal yang sangat subjektif, tetapi biasanya jika saya menggunakan beberapa tabel hanya untuk memfilter baris dari tabel utama kueri (seperti dalam kueri ini, kami hanya ingin mendapatkan awards untuk tahun 2012 dan cukup filter baris dari awardwinner ), saya lebih suka untuk tidak menggunakan join , tetapi gunakan exists atau in sebaliknya, tampaknya lebih logis bagi saya.
Jadi kueri terakhir dapat berupa:
with cte_s as (
    select
        aw.id_movie,
        count(*) as awards,
        rank() over(order by count(*) desc) as rnk
    from awardwinner as aw
    where
        exists (
            select *
            from award as a
            where a.id_award = aw.id_award and a.award_year = 2012
        )
    group by aw.id_movie
)
select id_movie
from cte_s
where rnk = 1


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Memilih Catatan dari 24 Jam Terakhir menggunakan PostgreSQL

  2. PostgreSQL:Loop Hingga Kondisi Benar

  3. Menggunakan UUID dengan EclipseLink dan PostgreSQL

  4. ClassCastException:Integer tidak dapat dilemparkan ke Long, saat mencoba mengulangi ID entitas

  5. UPDATE .. BATAS 1 dengan SqlAlchemy dan PostgreSQL