Bantuan SQL dengan permintaan MAX

Saya memiliki tabel negara bernama bbc(nama, wilayah, wilayah, populasi, PDB)

Saya ingin tabel dengan wilayah, nama dan populasi negara terbesar (terbanyak penduduknya) berdasarkan wilayah. Sejauh ini saya sudah mencoba ini:

SELECT region, name, MAX(population)
FROM bbc
GROUP BY region

Itu memberi saya pesan kesalahan: ORA-00979: Bukan Ekspresi GROUP BY

Saya mencoba mengubah ke GROUP BY region, nama, tetapi tidak memberikan tabel yang tepat


person tiagovrtr    schedule 09.07.2011    source sumber
comment
Apa yang terjadi dengan MAX(population) ke-2? Di mana Anda pernah melihatnya dilakukan?   -  person mechanical_meat    schedule 09.07.2011
comment
Oke, tapi jangan sampai terulang lagi :p   -  person mechanical_meat    schedule 10.07.2011


Jawaban (3)


Inilah cara termudah dan terpendek untuk melakukannya, karena Oracle memiliki pengujian tuple, ini dapat membuat kode menjadi lebih pendek:

Pertama, dapatkan populasi maksimal di setiap wilayah:

SELECT region, MAX(population)
FROM bbc
GROUP BY region

Kemudian ujilah negara-negara yang menentangnya:

select region, name, population 
from bbc 
where (region, population) in
      (SELECT region, MAX(population)
       FROM bbc
       GROUP BY region)
order by region

Jika Anda ingin mendukung banyak RDBMS, gunakan EXISTS:

select region, name, population 
from bbc o
where exists
      (SELECT null -- neutral. doesn't invoke Cargo Cult Programming ;-)
       FROM bbc
       WHERE region = o.region 
       GROUP BY region
       HAVING o.population = MAX(population) )
order by region

Kueri diuji di sini, keduanya memiliki keluaran serupa: http://sqlzoo.net/0.htm

http://www.ienablemuch.com/2010/05/why-is-exists-select-1-cargo-cult.html

person Michael Buen    schedule 10.07.2011
comment
Kedua kueri ini memiliki biaya yang lebih tinggi (Explain Plan) dibandingkan kueri yang menggunakan analitik. Itu semua tergantung pada tujuan Anda. - person DCookie; 10.07.2011
comment
Apakah itu pernyataan yang jelas-jelas ;-) apa yang kita lakukan sebelum analisis? Saya dapat menebak bahwa ada lebih banyak hal ilmu komputer yang diterapkan pada pendekatan itu daripada analitik, bahwa fungsionalitas tersebut sudah ada jauh sebelum CTE/Windowing/Analytics muncul. Dari segi implementasi C/C++, Analytics memiliki banyak ifs di dalamnya, ia menangani banyak fungsi, jadi apakah bisa lebih lambat? Mungkin. Hanya 2 sen saya. Jawabannya adalah profil - person Michael Buen; 10.07.2011
comment
Tidak ada bukti sama sekali - hanya pengamatan tentang berapa biaya yang menurut pengoptimal akan diperlukan untuk mengeksekusi kueri. Anda benar sekali bahwa buktinya ada pada metrik. - person DCookie; 10.07.2011

Anda dapat menggunakan analitik untuk pertanyaan seperti itu:

SELECT name, region, population
  FROM (SELECT region, name, population
             , MAX(population) OVER (PARTITION BY region) maxpop
          FROM bbc)
 WHERE population = maxpop;

Tampilan sebaris memberi Anda tabel yang terlihat seperti tabel dasar, ditambah kolom tambahan dengan populasi maksimal untuk wilayah tersebut. Pilihan tingkat teratas memberi Anda negara, wilayah, dan populasi negara terbesar di setiap wilayah.

Untuk mengilustrasikannya dengan contoh terbatas:

SELECT * FROM bbc;

REGION          NAME        POPULATION
--------------- -------     ----------
North America   USA         300000000
North America   Canada      100000000
North America   Mexico       50000000
South America   Brazil       50000000
South America   Argentina    40000000
South America   Venezuela    20000000

Tambahkan fungsi analitik:

SELECT region, NAME, population
     , MAX(population) OVER (PARTITION BY region) maxpop
  FROM bbc;

REGION          NAME                POPULATION      MAXPOP
--------------- -------             ----------      ----------
North America   USA                 300000000       300000000
North America   Canada              100000000       300000000
North America   Mexico               50000000       300000000
South America   Brazil               50000000        50000000
South America   Argentina            40000000        50000000
South America   Venezuela            20000000        50000000

Kemudian produk jadi:

NAME    REGION             POPULATION
------- ---------------    -----------
USA     North America       300000000
Brazil  South America        50000000

Satu kali edit lagi. Anda dapat menghindari pemilihan sarang, tetapi bukan subkueri:

SELECT NAME, region, population
  FROM bbc
 WHERE (region, population) IN
       (SELECT region, MAX(population)
          FROM bbc
         group by region);
person DCookie    schedule 09.07.2011
comment
Untuk wilayah tertentu, jika dua negara memiliki populasi yang sama (yang menurut saya sangat tidak mungkin, tetapi pertanyaan ini selalu layak ditanyakan), pertanyaan ini akan mengembalikan keduanya: apakah ini yang ditunggu oleh tiagovrtr? - person Bruno Gautier; 10.07.2011
comment
Siapa tahu? Tidak ada dalam persyaratan! - person DCookie; 10.07.2011
comment
@BrunoGautier tentu saja berhasil, tetapi saya mencoba untuk tidak menggunakan pilihan bersarang. Apakah itu tidak mungkin? - person tiagovrtr; 10.07.2011
comment
@OMG, selalu ada lebih dari satu cara untuk melakukannya ;-) Saya ingin tahu apakah ada perbedaan kinerja.... - person DCookie; 10.07.2011
comment
@tiagovtr, tidak yakin mengapa Anda ingin menghindari pilihan bersarang, tetapi hasil edit saya menunjukkan cara melakukannya dengan subkueri. - person DCookie; 10.07.2011
comment
@tiagovrtr, mengapa pilihan tidak disarangkan? Menurut saya kueri dengan pilihan bertingkat biasanya lebih mudah dibaca karena Anda dapat lebih mudah melihat langkah-langkah yang diperlukan untuk mencapai hasil akhir, terutama saat menggunakan analitik. Dan saya juga lebih mudah menebak rencana pelaksanaannya. - person Bruno Gautier; 10.07.2011
comment
@OMG, saya memang berpikir untuk menggunakan fungsi ‹code›ROW_NUMBER‹/code› ;-) - person Bruno Gautier; 10.07.2011
comment
@DCookie, saya suka ilustrasi Anda, ini menunjukkan dengan baik alasan di balik penggunaan analitik. - person Bruno Gautier; 10.07.2011

Di sebagian besar vas, kesalahan ORA-00979 disebabkan karena kolom non-agregat tidak termasuk dalam klausa GROUP BY. Dalam hal ini Anda perlu memasukkan nama juga dalam klausa GROUP BY Anda. Selain itu, Anda tidak boleh memanggil fungsi MAX dalam pernyataan FROM Anda.

SELECT region, name, MAX(population)
FROM bbc
GROUP BY region, name
person THE DOCTOR    schedule 09.07.2011