Apakah ada cara yang lebih baik untuk melakukan kueri seperti ini:
SELECT COUNT(*)
FROM (SELECT DISTINCT DocumentId, DocumentSessionId
FROM DocumentOutputItems) AS internalQuery
Saya perlu menghitung jumlah item berbeda dari tabel ini tetapi perbedaannya lebih dari dua kolom.
Permintaan saya berfungsi dengan baik tetapi saya bertanya-tanya apakah saya bisa mendapatkan hasil akhir hanya dengan menggunakan satu permintaan (tanpa menggunakan sub-permintaan)
sql
sql-server
performance
tsql
query-optimization
Novitzky
sumber
sumber
Jawaban:
Jika Anda mencoba untuk meningkatkan kinerja, Anda bisa mencoba membuat kolom yang dihitung tetap pada nilai hash atau gabungan dari kedua kolom.
Setelah dipertahankan, asalkan kolom bersifat deterministik dan Anda menggunakan pengaturan basis data "waras", itu dapat diindeks dan / atau statistik dapat dibuat di atasnya.
Saya yakin jumlah berbeda dari kolom yang dihitung akan setara dengan kueri Anda.
sumber
Sunting: Diubah dari permintaan checksum-only yang kurang dapat diandalkan, saya telah menemukan cara untuk melakukan ini (dalam SQL Server 2005) yang bekerja cukup baik untuk saya dan saya dapat menggunakan kolom sebanyak yang saya butuhkan (dengan menambahkannya ke fungsi CHECKSUM ()). Fungsi REVERSE () mengubah int menjadi varchars untuk membuat perbedaan lebih dapat diandalkan
sumber
Ada apa dengan kueri Anda saat ini yang tidak Anda sukai? Jika Anda khawatir bahwa
DISTINCT
di dua kolom tidak hanya mengembalikan permutasi unik mengapa tidak mencobanya?Ini tentu berfungsi seperti yang Anda harapkan di Oracle.
sunting
Saya pergi ke jalan buntu dengan analitik tetapi jawabannya sangat jelas ...
edit 2
Mengingat data berikut, solusi gabungan yang disediakan di atas akan salah hitung:
Jadi kita memasukkan pemisah ...
Jelas pemisah yang dipilih harus berupa karakter, atau serangkaian karakter, yang tidak akan pernah muncul di kolom mana pun.
sumber
Untuk menjalankan sebagai kueri tunggal, gabungkan kolom, lalu dapatkan jumlah instance instance string yang digabungkan.
Di MySQL Anda dapat melakukan hal yang sama tanpa langkah penyatuan sebagai berikut:
Fitur ini disebutkan dalam dokumentasi MySQL:
http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_count-distinct
sumber
SELECT COUNT(DISTINCT (DocumentId, DocumentSessionId)) FROM DocumentOutputItems;
Bagaimana dengan sesuatu seperti:
Mungkin hanya melakukan hal yang sama seperti yang sudah Anda lakukan tetapi itu menghindari yang berbeda.
sumber
GROUP BY
dapat memperkenalkan beberapa tantangan tambahan pada transformasi kueri untuk mencapai output yang diinginkan (mis. Ketika kueri asli sudah memilikiGROUP BY
atauHAVING
klausa ...)Ini versi yang lebih pendek tanpa subselect:
Ini berfungsi dengan baik di MySQL, dan saya pikir pengoptimal memiliki waktu lebih mudah memahami yang ini.
Sunting: Rupanya saya salah membaca MSSQL dan MySQL - maaf soal itu, tapi mungkin bisa membantu.
sumber
count ( distinct CHECKSUM ([Field1], [Field2])
Banyak (sebagian besar?) Basis data SQL dapat bekerja dengan tuple seperti nilai sehingga Anda bisa melakukannya:
SELECT COUNT(DISTINCT (DocumentId, DocumentSessionId)) FROM DocumentOutputItems;
Jika basis data Anda tidak mendukung ini, dapat disimulasikan sesuai dengan saran @SELUM-Umut-turer dari CHECKSUM atau fungsi skalar lainnya yang memberikan keunikan yang baik misCOUNT(DISTINCT CONCAT(DocumentId, ':', DocumentSessionId))
.Penggunaan terkait tuple sedang dilakukan
IN
kueri seperti:SELECT * FROM DocumentOutputItems WHERE (DocumentId, DocumentSessionId) in (('a', '1'), ('b', '2'));
sumber
select count(distinct(a, b))
? : DTidak ada yang salah dengan permintaan Anda, tetapi Anda juga bisa melakukannya dengan cara ini:
sumber
Semoga ini berfungsi saya menulis di prima vista
sumber
Saya telah menggunakan pendekatan ini dan itu berhasil bagi saya.
Untuk kasus saya, ini memberikan hasil yang benar.
sumber
jika Anda hanya memiliki satu bidang untuk "DISTINCT", Anda dapat menggunakan:
dan itu mengembalikan rencana permintaan yang sama seperti aslinya, seperti diuji dengan SET SHOWPLAN_ALL ON. Namun Anda menggunakan dua bidang sehingga Anda dapat mencoba sesuatu yang gila seperti:
tetapi Anda akan memiliki masalah jika NULL terlibat. Saya hanya akan tetap dengan permintaan asli.
sumber
Saya menemukan ini ketika saya mencari di Google untuk masalah saya sendiri, menemukan bahwa jika Anda menghitung objek yang berbeda, Anda mendapatkan nomor yang benar kembali (saya menggunakan MySQL)
sumber
DocumentId
danDocumentSessionId
). Alexander Kjäll sudah memposting jawaban yang benar jika OP menggunakan MySQL dan bukan MS SQL Server.Saya berharap MS SQL juga dapat melakukan sesuatu seperti COUNT (PERPINDAHAN A, B). Tetapi tidak bisa.
Awalnya jawaban JayTee sepertinya solusi bagi saya bu setelah beberapa tes CHECKSUM () gagal menciptakan nilai-nilai unik. Contoh singkatnya adalah, CHECKSUM (31.467.519) dan CHECKSUM (69.1111.823) memberikan jawaban yang sama yaitu 55.
Kemudian saya melakukan riset dan menemukan bahwa Microsoft TIDAK merekomendasikan menggunakan CHECKSUM untuk tujuan deteksi perubahan. Di beberapa forum beberapa disarankan menggunakan
tapi ini juga tidak nyaman.
Anda dapat menggunakan fungsi HASHBYTES () seperti yang disarankan dalam teka-teki TSQL CHECKSUM . Namun ini juga memiliki peluang kecil untuk tidak memberikan hasil yang unik.
Saya sarankan menggunakan
sumber
Bagaimana dengan ini,
Ini akan membuat kita menghitung semua kombinasi yang mungkin dari DocumentId, dan DocumentSessionId
sumber
Ini bekerja untuk saya. Di oracle:
Dalam jpql:
sumber
Saya memiliki pertanyaan serupa tetapi pertanyaan saya adalah sub-permintaan dengan data perbandingan dalam permintaan utama. sesuatu seperti:
mengabaikan kompleksitas ini, saya menyadari saya tidak bisa mendapatkan nilai a.code ke dalam subquery dengan permintaan sub ganda yang dijelaskan dalam pertanyaan asli
Jadi akhirnya saya tahu saya bisa menipu, dan menggabungkan kolom:
Inilah yang akhirnya berhasil
sumber
Jika Anda bekerja dengan tipe data panjang tetap, Anda dapat
binary
melakukan hal ini dengan sangat mudah dan sangat cepat. Dengan asumsiDocumentId
danDocumentSessionId
keduanyaint
s, dan karena itu panjangnya 4 byte ...Masalah khusus saya mengharuskan saya untuk membagi
SUM
denganCOUNT
kombinasi yang berbeda dari berbagai kunci asing dan bidang tanggal, pengelompokan dengan kunci asing lain dan kadang-kadang penyaringan dengan nilai atau kunci tertentu. Tabelnya sangat besar, dan menggunakan sub-kueri secara dramatis meningkatkan waktu kueri. Dan karena kerumitannya, statistik bukanlah pilihan yang layak. TheCHECKSUM
solusi adalah juga terlalu lambat dalam konversi, terutama sebagai akibat dari berbagai jenis data, dan saya tidak bisa mengambil risiko tidak dapat diandalkan.Namun, menggunakan solusi di atas hampir tidak ada peningkatan pada waktu permintaan (dibandingkan dengan hanya menggunakan
SUM
), dan harus sepenuhnya dapat diandalkan! Seharusnya bisa membantu orang lain dalam situasi yang sama jadi saya mempostingnya di sini.sumber
Anda bisa menggunakan Count Function Twice.
Dalam hal ini, itu akan menjadi:
sumber
Kode ini menggunakan perbedaan pada 2 parameter dan memberikan jumlah jumlah baris yang spesifik untuk jumlah baris yang berbeda tersebut. Ini bekerja untuk saya di MySQL seperti pesona.
sumber