Saya belajar sesuatu yang sederhana tentang SQL tempo hari:
SELECT c FROM myTbl GROUP BY C
Memiliki hasil yang sama dengan:
SELECT DISTINCT C FROM myTbl
Apa yang saya ingin tahu, apakah ada yang berbeda dalam cara mesin SQL memproses perintah, atau apakah mereka benar-benar hal yang sama?
Saya pribadi lebih suka sintaks yang berbeda, tetapi saya yakin itu lebih karena kebiasaan daripada yang lain.
EDIT: Ini bukan pertanyaan tentang agregat. Penggunaan GROUP BY
dengan fungsi agregat dipahami.
SELECT c FROM myTbl UNION SELECT c FROM myTbl
dan mendapatkan hasil yang sama ... Tetapi mengapa menyulitkan hal-hal ketika SELECT DISTINCT sangat mudah.GROUP BY
jauh lebih awal dari 'PILIH' danDISTINCT
ikuti pilih.DISTINCT
hasil dalam benar-benar memilih bidang - yaitu nilai akan muncul di set hasil.GROUP BY
dapat secara efektif menghapus duplikat tanpa benar-benar memilih bidang. Ini agak tidak relevan dalam banyak kasus, tetapi bisa jadi persis seperti yang Anda inginkan pada orang lain. Jika Anda akhirnya menggunakanGROUP BY
menggantikanDISTINCT
, komentar penjelasan dalam kode mungkin dijamin.Jawaban:
Respons MusiGenesis 'secara fungsional adalah yang benar sehubungan dengan pertanyaan Anda sebagaimana dinyatakan; SQL Server cukup pintar untuk menyadari bahwa jika Anda menggunakan "Group By" dan tidak menggunakan fungsi agregat, maka apa yang Anda maksud sebenarnya adalah "Distinct" - dan karena itu menghasilkan rencana eksekusi seolah-olah Anda hanya akan menggunakan "Distinct" . "
Namun, saya pikir ini penting untuk mencatat respons Hank juga - perawatan gagah berani dari "Group By" dan "Distinct" dapat menyebabkan beberapa gotchas berbahaya di telepon jika Anda tidak hati-hati. Tidak sepenuhnya benar untuk mengatakan bahwa ini "bukan pertanyaan tentang agregat" karena Anda bertanya tentang perbedaan fungsional antara dua kata kunci kueri SQL, yang salah satunya dimaksudkan untuk digunakan dengan agregat dan yang salah satunya tidak.
Palu kadang-kadang bisa berfungsi untuk mengendarai sekrup, tetapi jika Anda punya obeng, mengapa repot-repot?
(untuk keperluan analogi ini,
Hammer : Screwdriver :: GroupBy : Distinct
danscrew => get list of unique values in a table column
)sumber
GROUP BY
memungkinkan Anda menggunakan fungsi agregat, sepertiAVG
,MAX
,MIN
,SUM
, danCOUNT
. Di sisi lainDISTINCT
hanya menghapus duplikat.Misalnya, jika Anda memiliki banyak catatan pembelian, dan Anda ingin tahu berapa banyak yang dihabiskan oleh masing-masing departemen, Anda mungkin melakukan sesuatu seperti:
Ini akan memberi Anda satu baris per departemen, yang berisi nama departemen dan jumlah semua
amount
nilai di semua baris untuk departemen itu.sumber
DISTINCT
fungsi agregat +? seperti ini:select distinct department, SUM(amount) from ...
Tidak ada perbedaan (dalam SQL Server, setidaknya). Kedua pertanyaan menggunakan rencana eksekusi yang sama.
http://sqlmag.com/database-performance-tuning/distinct-vs-group
Mungkin ada yang perbedaan, jika ada sub-query terlibat:
http://blog.sqlauthority.com/2007/03/29/sql-server-difference-between-distinct-and-group-by-distinct-vs-group-by/
Tidak ada perbedaan (gaya Oracle):
http://asktom.oracle.com/pls/asktom/f?p=100:11*::::P11_QUESTION_ID:32961403234212
sumber
Apa bedanya dari sudut pandang fungsi penghilangan duplikat belaka
Terlepas dari kenyataan bahwa tidak seperti
DISTINCT
,GROUP BY
memungkinkan untuk mengumpulkan data per kelompok (yang telah disebutkan oleh banyak jawaban lain), perbedaan paling penting menurut saya adalah kenyataan bahwa dua operasi "terjadi" pada dua langkah yang sangat berbeda dalam urutan logis operasi yang dieksekusi dalam sebuahSELECT
pernyataan .Berikut adalah operasi yang paling penting:
FROM
(termasukJOIN
,APPLY
, dll)WHERE
GROUP BY
(dapat menghapus duplikat)HAVING
SELECT
DISTINCT
(dapat menghapus duplikat)UNION
,INTERSECT
,EXCEPT
(Dapat menghapus duplikat)ORDER BY
OFFSET
LIMIT
Seperti yang Anda lihat, urutan logis dari setiap operasi memengaruhi apa yang dapat dilakukan dengannya dan bagaimana hal itu memengaruhi operasi berikutnya. Secara khusus, fakta bahwa
GROUP BY
operasi "terjadi sebelum" yangSELECT
operasi (proyeksi) berarti bahwa:1. Itu tidak tergantung pada proyeksi
Contoh di mana tidak tergantung pada proyeksi berguna adalah jika Anda ingin menghitung fungsi jendela pada nilai yang berbeda:
Ketika dijalankan terhadap basis data Sakila , ini menghasilkan:
Hal yang sama tidak dapat dicapai dengan
DISTINCT
mudah:Kueri itu "salah" dan menghasilkan sesuatu seperti:
Ini bukan yang kita inginkan. The
DISTINCT
Operasi "terjadi setelah" proyeksi, sehingga kita tidak lagi dapat menghapusDISTINCT
peringkat karena fungsi jendela sudah dihitung dan diproyeksikan. Untuk menggunakanDISTINCT
, kami harus membuat sarang bagian dari permintaan itu:Catatan: Dalam kasus khusus ini, kita juga bisa menggunakan
DENSE_RANK()
2. Tidak dapat menggunakan nilai apa pun dari proyeksi
Salah satu kelemahan SQL adalah verbositasnya. Untuk alasan yang sama seperti apa yang telah kita lihat sebelumnya (yaitu urutan operasi logis), kita tidak dapat "dengan mudah" mengelompokkan berdasarkan sesuatu yang kita proyeksikan.
Ini adalah SQL yang tidak valid:
Ini valid (mengulangi ungkapan)
Ini juga berlaku (bersarang ekspresi)
Saya telah menulis tentang topik ini secara lebih mendalam dalam sebuah posting blog
sumber
WHERE
tapi mungkinGROUP BY
). Bagaimanapun, saya pikir itu ide yang buruk dan saya sarankan tidak pernah menggunakan fitur itu untuk alasan portabilitas dan pemeliharaan. "Tiba-tiba" itu tidak akan berfungsi lagi, misalnya ketika aliasing fungsi agregat atau fungsi jendela.never using that feature for portability and maintenance reasons
!! setuju 100% ... & Saya sekarang sedang enjot blog Anda, kerja bagus Bersulang.Gunakan
DISTINCT
jika Anda hanya ingin menghapus duplikat. GunakanGROUPY BY
jika Anda ingin menerapkan operator agregat (MAX
,SUM
,GROUP_CONCAT
, ..., atauHAVING
klausa).sumber
Saya berharap ada kemungkinan perbedaan halus dalam eksekusi mereka. Saya memeriksa rencana eksekusi untuk dua kueri fungsional yang setara di sepanjang baris ini di Oracle 10g:
Operasi tengah sedikit berbeda: "HASH GROUP BY" vs "HASH UNIQUE", tetapi perkiraan biaya dll identik. Saya kemudian menjalankan ini dengan melacak dan jumlah operasi yang sebenarnya sama untuk keduanya (kecuali bahwa yang kedua tidak harus melakukan pembacaan fisik karena caching).
Tapi saya pikir itu karena nama operasi berbeda, eksekusi akan mengikuti jalur kode yang agak berbeda dan yang membuka kemungkinan perbedaan yang lebih signifikan.
Saya pikir Anda harus memilih sintaks DISTINCT untuk tujuan ini. Ini bukan hanya kebiasaan, itu lebih jelas menunjukkan tujuan permintaan.
sumber
Untuk kueri yang Anda poskan, keduanya identik. Tetapi untuk pertanyaan lain yang mungkin tidak benar.
Misalnya, ini tidak sama dengan:
sumber
Saya membaca semua komentar di atas tetapi tidak melihat ada yang menunjuk ke perbedaan utama antara Group By dan Distinct selain dari sedikit agregasi.
Distinct mengembalikan semua baris kemudian menduplikatnya sedangkan Grup By-mendupuplikat baris saat mereka dibaca oleh algoritma satu per satu.
Ini berarti mereka dapat menghasilkan hasil yang berbeda!
Misalnya, kode di bawah ini menghasilkan hasil yang berbeda:
Jika ada 10 nama dalam tabel di mana 1 di antaranya merupakan duplikat dari yang lain maka kueri pertama mengembalikan 10 baris sedangkan kueri kedua mengembalikan 9 baris.
Alasannya adalah apa yang saya katakan di atas sehingga mereka dapat berperilaku berbeda!
sumber
Name
dalam kueri kedua,distinct
kata kunci berlaku untuk kolomName
danROW_NUMBER()
kolom Anda dalamselect
klausa dari kueri pertama. Seandainya Anda juga dikelompokkan berdasarkan kolom pertama dalam kueri kedua, kueri akan mengembalikan hasil yang sama.order of execution
klausa SQL yang (dalam pengertian umum)FROM and ON (joins)
,WHERE
,GROUP BY
,HAVING
,SELECT
,DISTINCT
,ORDER BY
,LIMIT / OFFSET / TOP
sehingga permintaan kedua nama berkurang jumlahnya oleh kelompok dengan dan kemudian row_number () diterapkan mengakibatkan satu baris per nama unik. Dalam kueri pertama, row_number () diterapkan sebelum perbedaan diterapkan, dan karena sifat fungsi row_number () setiap baris mendapat bilangan bulat yang unik, sehingga setiap baris dikembalikan bahkan jika ada nilai nama yang diulang.Jika Anda menggunakan DISTINCT dengan beberapa kolom, set hasil tidak akan dikelompokkan seperti halnya dengan GROUP BY, dan Anda tidak dapat menggunakan fungsi agregat dengan DISTINCT.
sumber
Mereka memiliki semantik yang berbeda, bahkan jika mereka memiliki hasil yang setara pada data khusus Anda.
sumber
GROUP BY memiliki makna yang sangat spesifik yang berbeda (heh) dari fungsi DISTINCT.
GROUP BY menyebabkan hasil kueri dikelompokkan menggunakan ekspresi yang dipilih, fungsi agregat kemudian dapat diterapkan, dan ini akan bertindak pada masing-masing kelompok, daripada seluruh resultset.
Berikut ini contoh yang mungkin membantu:
Diberikan tabel yang terlihat seperti ini:
Kueri ini:
Akan menghasilkan output seperti ini:
Yang jelas sangat berbeda dengan menggunakan DISTINCT. Jika Anda ingin mengelompokkan hasil Anda, gunakan GROUP BY, jika Anda hanya ingin daftar unik kolom tertentu, gunakan DISTINCT. Ini akan memberi Anda basis data peluang untuk mengoptimalkan kueri untuk kebutuhan Anda.
sumber
Tolong jangan gunakan GROUP BY ketika maksud Anda DISTINCT, bahkan jika mereka bekerja dengan cara yang sama. Saya berasumsi Anda mencoba untuk memangkas milidetik dari pertanyaan, dan saya harus menunjukkan bahwa waktu pengembang adalah pesanan besarnya lebih mahal daripada waktu komputer.
sumber
Jika Anda menggunakan GROUP BY tanpa fungsi agregat maka secara internal akan diperlakukan sebagai DISTINCT, jadi dalam hal ini tidak ada perbedaan antara GROUP BY dan DISTINCT.
Tetapi ketika Anda diberikan klausa DISTINCT lebih baik untuk menggunakannya untuk menemukan catatan unik Anda karena tujuan dari GROUP BY adalah untuk mencapai agregasi.
sumber
dikelompokkan oleh digunakan dalam operasi agregat - seperti ketika Anda ingin mendapatkan hitungan B yang dipecah oleh kolom C
berbeda seperti apa itu terdengar - Anda mendapatkan baris yang unik.
Di sql server 2005, sepertinya pengoptimal kueri dapat mengoptimalkan perbedaan dalam contoh sederhana yang saya jalankan. Tidak tahu apakah Anda dapat mengandalkan itu dalam semua situasi.
sumber
Dalam kueri tertentu tidak ada perbedaan. Tetapi, tentu saja, jika Anda menambahkan kolom agregat apa pun maka Anda harus menggunakan grup berdasarkan.
sumber
Dalam perspektif Teradata :
Dari sudut pandang set hasil, tidak masalah jika Anda menggunakan DISTINCT atau GROUP BY di Teradata. Set jawaban akan sama.
Dari sudut pandang kinerja, itu tidak sama.
Untuk memahami apa yang memengaruhi kinerja, Anda perlu tahu apa yang terjadi pada Teradata ketika menjalankan pernyataan dengan DISTINCT atau GROUP BY.
Dalam kasus DISTINCT, baris-baris didistribusikan kembali dengan segera tanpa terjadi pragregasi, sedangkan dalam kasus GROUP BY, pada langkah pertama pragregasi dilakukan dan baru kemudian nilai-nilai unik tersebut didistribusikan kembali di seluruh AMP.
Jangan berpikir sekarang bahwa GROUP BY selalu lebih baik dari sudut pandang kinerja. Ketika Anda memiliki banyak nilai berbeda, langkah preagregasi GROUP BY tidak terlalu efisien. Teradata harus mengurutkan data untuk menghapus duplikat. Dalam hal ini, mungkin lebih baik melakukan redistribusi terlebih dahulu, yaitu menggunakan pernyataan DISTINCT. Hanya jika ada banyak nilai duplikat, pernyataan GROUP BY mungkin adalah pilihan yang lebih baik karena hanya sekali langkah deduplikasi terjadi, setelah redistribusi.
Singkatnya, DISTINCT vs. GROUP BY dalam Teradata berarti:
KELOMPOK OLEH -> untuk banyak duplikat DISTINCT -> tidak atau beberapa duplikat saja. Terkadang, saat menggunakan DISTINCT, Anda kehabisan ruang spool pada AMP. Alasannya adalah redistribusi terjadi segera, dan kemiringan dapat menyebabkan AMP kehabisan ruang.
Jika ini terjadi, Anda mungkin memiliki peluang yang lebih baik dengan GROUP BY, karena duplikat sudah dihapus pada langkah pertama, dan lebih sedikit data yang dipindahkan di seluruh AMP.
sumber
Teradata
?Dari perspektif 'SQL the language', kedua konstruk itu setara dan mana yang Anda pilih adalah salah satu dari pilihan 'gaya hidup' yang harus kita buat. Saya pikir ada kasus yang baik untuk DISTINCT menjadi lebih eksplisit (dan oleh karena itu lebih perhatian kepada orang yang akan mewarisi kode Anda dll) tetapi itu tidak berarti konstruksi GROUP BY adalah pilihan yang tidak valid.
Saya pikir 'GROUP BY is for aggregate' ini adalah penekanan yang salah. Rakyat harus menyadari bahwa fungsi yang ditetapkan (MAX, MIN, COUNT, dll) dapat dihilangkan sehingga mereka dapat memahami maksud pembuat kode ketika itu.
Pengoptimal yang ideal akan mengenali konstruksi SQL yang setara dan akan selalu memilih paket ideal yang sesuai. Untuk mesin SQL kehidupan nyata pilihan Anda, Anda harus menguji :)
PS perhatikan posisi kata kunci DISTINCT dalam klausa pilih dapat menghasilkan hasil yang berbeda misalnya kontras:
sumber
Anda hanya memperhatikan itu karena Anda memilih satu kolom.
Coba pilih dua bidang dan lihat apa yang terjadi.
Group By dimaksudkan untuk digunakan seperti ini:
Yang akan menunjukkan jumlah semua transaksi untuk setiap orang.
sumber
Saya tahu ini posting lama. Tapi itu terjadi bahwa saya memiliki permintaan yang menggunakan grup hanya untuk mengembalikan nilai yang berbeda ketika menggunakan permintaan itu dalam kodok dan laporan oracle semuanya bekerja dengan baik, maksud saya waktu respons yang baik. Ketika kami bermigrasi dari Oracle 9i ke 11g waktu respons di Toad sangat bagus, tetapi dalam laporan itu butuh sekitar 35 menit untuk menyelesaikan laporan saat menggunakan versi sebelumnya, butuh sekitar 5 menit.
Solusinya adalah mengubah grup dengan dan menggunakan DISTINCT dan sekarang laporan berjalan sekitar 30 detik.
Saya harap ini berguna untuk seseorang dengan situasi yang sama.
sumber
Dalam hal penggunaan, GROUP BY digunakan untuk mengelompokkan baris yang ingin Anda hitung. DISTINCT tidak akan melakukan perhitungan. Tidak akan ada baris duplikat.
Saya selalu menggunakan DISTINCT jika saya ingin menyajikan data tanpa duplikat.
Jika saya ingin melakukan perhitungan seperti merangkum jumlah total mangga, saya akan menggunakan GROUP BY
sumber
Cara saya selalu memahaminya adalah bahwa menggunakan berbeda sama dengan pengelompokan oleh setiap bidang yang Anda pilih dalam urutan yang Anda pilih.
yaitu:
sama dengan:
sumber
Efisiensi funtional sama sekali berbeda. Jika Anda hanya ingin memilih "nilai pengembalian" kecuali duplikat, gunakan berbeda lebih baik daripada dikelompokkan berdasarkan. Karena "dikelompokkan berdasarkan" termasuk (menyortir + menghapus), "berbeda" termasuk (menghapus)
sumber
Dalam Hive (HQL), grup dengan bisa jauh lebih cepat daripada yang berbeda, karena yang pertama tidak perlu membandingkan semua bidang dalam tabel. Lihat https://sqlperformance.com/2017/01/t-sql-queries/surprises-assumptions-group-by-distinct .
sumber
Kadang-kadang mereka dapat memberi Anda hasil yang sama tetapi mereka dimaksudkan untuk digunakan dalam arti / kasus yang berbeda. Perbedaan utama adalah dalam sintaksis.
Perhatikan baik-baik contoh di bawah ini.
DISTINCT
digunakan untuk menyaring set nilai duplikat. (6, cs, 9.1) dan (1, cs, 5.5) adalah dua set yang berbeda. JadiDISTINCT
akan menampilkan kedua baris sementaraGROUP BY Branch
akan menampilkan hanya satu set.Terkadang hasil yang dapat dicapai dengan
GROUP BY
klausa tidak mungkin dicapaiDISTINCT
tanpa menggunakan beberapa klausa atau ketentuan tambahan. Misalnya dalam kasus di atas.Untuk mendapatkan hasil yang sama seperti
DISTINCT
Anda harus melewati semua nama kolom dalamGROUP BY
klausa seperti di bawah ini. Jadi lihat perbedaan sintaksisnya. Anda harus memiliki pengetahuan tentang semua nama kolom untuk menggunakanGROUP BY
klausa dalam kasus itu.Saya juga telah memperhatikan
GROUP BY
menampilkan hasil dalam urutan naik secara default yangDISTINCT
tidak. Tetapi saya tidak yakin tentang ini. Mungkin berbeda dari vendor.Sumber: https://dbjpanda.me/dbms/languages/sql/sql-syntax-with-examples#group-by
sumber
Secara umum kita bisa menggunakan
DISTINCT
untuk menghilangkan duplikat pada kolom khusus dalam tabel.Contoh:
sumber
Tidak ada perbedaan yang signifikan antara grup dengan dan klausa yang berbeda kecuali penggunaan fungsi agregat. Keduanya dapat digunakan untuk membedakan nilai-nilai tetapi jika dalam sudut pandang kinerja kelompok lebih baik. Ketika kata kunci yang berbeda digunakan, secara internal ia menggunakan semacam operasi yang dapat dilihat dalam rencana eksekusi.
Coba contoh sederhana
Nyatakan tabel @tmpresult (Id tinyint)
Masukkan ke @tmpresult Select 5 Union all Select 2 Union all Pilih 3 Union all Select 4
Pilih Id berbeda dari @tmpresult
sumber