Laravel Eloquent - different () dan count () tidak bekerja sama dengan baik

99

Jadi saya mencoba mendapatkan jumlah pids berbeda pada kueri, tetapi nilai yang dikembalikan salah.

Inilah yang saya coba lakukan:

$ad->getcodes()->groupby('pid')->distinct()->count()

apa yang mengembalikan nilai "2", sedangkan nilai yang harus dikembalikan, harus "1".

Sebagai solusinya, saya melakukan ini:

count($ad->getcodes()->groupby('pid')->distinct()->get())

apa yang berfungsi dengan baik dan mengembalikan "1"

Apakah ada aturan di mana hitungan dan perbedaan tidak boleh berada pada kueri yang sama? Saya menemukan solusi semacam itu "berat", saya ingin kueri asli berfungsi :(

Inigo EC
sumber
Apa yang Anda miliki di tabel sampel di database? Dan apa yang ingin Anda capai? Sekarang Anda mungkin harus mendapatkan jumlah nilai yang berbeda di pidkolom, jadi jika Anda memiliki dalam tabel Anda 2 catatan - satu dengan pid 1, kedua dengan pid 2, hitung harus
menghasilkan
Anda cukup mengganti get dengan hitungan dengan cara ini: $count = DB::table('tablename')->count(DB::raw('DISTINCT pid')); juga dapat melakukan: DB::table('tablename')->distinct('pid')->count('pid');
bharat

Jawaban:

128

Berikut ini seharusnya bekerja

$ad->getcodes()->distinct('pid')->count('pid');
Suresh Bala
sumber
2
Punya masalah serupa dan sepertinya membiarkan saja groupBytidak berhasil.
jeteon
8
Berbeda tidak membutuhkan argumen apa pun. Memanggil different () saat membuat kueri Anda hanya menyetel boolean yang dilindungi ke true, argumennya diabaikan.
Matt McDonald
Di L5.1 dan ini masih tidak berfungsi. Menggunakan count()tampaknya menonaktifkan atau menjatuhkan file distinct(). Gunakan groupBy()seperti yang dijelaskan di seluruh pertanyaan. Sunting: Saya menemukan bahkan groupBy()memberikan perbedaan count()dibandingkan get()diikuti dengan menghitung array yang dihasilkan.
Jason
@Jason saya membuat pengamatan yang sama seperti Anda. Lihat jawaban saya untuk solusinya.
Zoon
21
The distinct()Fungsi tidak membutuhkan argumen. Anda dapat mengubahnya menjadi $ad->getcodes()->distinct()->count('pid');dengan hasil yang sama.
Trevor Gehman
26

Jawaban yang lebih umum yang akan menghemat waktu saya, dan mudah-mudahan yang lain:

Tidak berfungsi (mengembalikan hitungan semua baris):

DB::table('users')
            ->select('first_name')
            ->distinct()
            ->count();

Cara mengatasinya:

DB::table('users')
            ->distinct()
            ->count('first_name');
Andrew
sumber
17

Adakah orang lain yang menemukan posting ini, dan tidak menemukan saran lain untuk berfungsi?

Bergantung pada kueri spesifik, pendekatan yang berbeda mungkin diperlukan. Dalam kasus saya, saya perlu menghitung hasil dari GROUP BY, misalnya

SELECT COUNT(*) FROM (SELECT * FROM a GROUP BY b)

atau gunakan COUNT(DISTINCT b):

SELECT COUNT(DISTINCT b) FROM a

Setelah beberapa kebingungan, saya menyadari tidak ada fungsi Laravel bawaan untuk salah satu dari ini. Jadi solusi paling sederhana adalah menggunakan use DB::rawwith the countmethod.

$count = $builder->count(DB::raw('DISTINCT b'));

Ingat, jangan gunakan groupBysebelum menelepon count. Anda dapat mendaftar groupBynanti, jika Anda membutuhkannya untuk mendapatkan baris.

Zoon
sumber
Dari mana $ builder berasal?
Andrew
1
@Andrew Pembuat kueri Laravel yang Anda gunakan untuk kueri. Misalnya, objek Eloquent$books = Book::where(...)->count(...)
Zoon
->count(DB::raw('DISTINCT b'))menghasilkan kueri SQL yang sama dengan->distinct()->count('b')
Trevor Gehman
5

Saya memiliki masalah serupa, dan menemukan cara untuk mengatasinya.

Masalahnya adalah cara pembuat kueri Laravel menangani agregat. Ini mengambil hasil pertama yang dikembalikan dan kemudian mengembalikan nilai 'agregat'. Ini biasanya baik-baik saja, tetapi ketika Anda menggabungkan hitungan dengan groupBy, Anda mengembalikan hitungan per item yang dikelompokkan. Jadi, agregat baris pertama hanyalah hitungan dari kelompok pertama (jadi kemungkinan kecil seperti 1 atau 2).

Jadi jumlah Laravel sudah habis, tetapi saya menggabungkan pembuat kueri Laravel dengan beberapa SQL mentah untuk mendapatkan jumlah akurat dari hasil yang saya kelompokkan.

Untuk contoh Anda, saya berharap yang berikut ini akan berhasil (dan membiarkan Anda menghindari get):

$query = $ad->getcodes()->groupby('pid')->distinct();
$count = count(\DB::select($query->toSql(), $query->getBindings()));

Jika Anda ingin memastikan Anda tidak membuang-buang waktu memilih semua kolom, Anda dapat menghindarinya saat membuat kueri:

 $query = $ad->select(DB::raw(1))->getcodes()->groupby('pid')->distinct();
Matt McDonald
sumber
4

Saya menemukan masalah yang sama.

Jika Anda menginstal bilah debug laravel, Anda dapat melihat kueri dan sering melihat masalahnya

$ad->getcodes()->groupby('pid')->distinct()->count()

mengubah

$ad->getcodes()->distinct()->select('pid')->count()

Anda perlu menyetel nilai untuk dikembalikan sebagai berbeda. Jika Anda tidak mengatur bidang pilih, itu akan mengembalikan semua kolom dalam database dan semuanya akan unik. Jadi setel kueri ke berbeda dan hanya pilih kolom yang membentuk nilai 'berbeda' Anda, Anda mungkin ingin menambahkan lebih banyak. ->select('pid','date')untuk mendapatkan semua nilai unik bagi pengguna dalam sehari

Brett
sumber
4

Anda dapat menggunakan cara berikut untuk mendapatkan data unik sesuai kebutuhan Anda sebagai berikut,

$data = $ad->getcodes()->get()->unique('email');

$count = $data->count();

Semoga ini berhasil.

Shahrukh Anwar
sumber
1

Bukankah ini akan berhasil?

$ad->getcodes()->distinct()->get(['pid'])->count();

Lihat di sini untuk diskusi ..

JonnyFoley
sumber
3
Ini bukan solusi yang baik, karena get()panggilan akan mengeksekusi kueri dan mengembalikan hasil dari database, lalu count()menjalankan Collection.
Trevor Gehman
1
$solution = $query->distinct()
            ->groupBy
            (
                [
                    'array',
                    'of',
                    'columns',
                ]
            )
            ->addSelect(
                [
                    'columns',
                    'from',
                    'the',
                    'groupby',
                ]
            )
            ->get();

Ingat grup oleh adalah opsional, ini harus bekerja dalam banyak kasus ketika Anda ingin grup hitungan dengan mengecualikan nilai pilih duplikat, addSelect adalah metode contoh querybuilder.

Daniel Santos
sumber
0

Berbeda tidak mengambil argumen karena menambahkan DISTINCT dalam kueri sql Anda, namun, Anda MUNGKIN perlu menentukan nama kolom yang ingin Anda pilih berbeda. Jadi, jika Anda memiliki Flight->select('project_id')->distinct()->get()sama dengan SELECT DISTINCT 'project_id' FROM flightsdan sekarang Anda dapat menambahkan pengubah lain seperti count () atau bahkan kueri fasih mentah.

Karl Anthony Baluyot
sumber
0

Berdasarkan dokumen Laravel untuk kueri mentah, saya bisa menghitung jumlah bidang pilihan untuk bekerja dengan kode ini dalam model produk.

public function scopeShowProductCount($query)
{
    $query->select(DB::raw('DISTINCT pid, COUNT(*) AS count_pid'))
          ->groupBy('pid')
          ->orderBy('count_pid', 'desc');
}

Fasad ini berfungsi untuk mendapatkan hasil yang sama di pengontrol:

$products = DB::table('products')->select(DB::raw('DISTINCT pid, COUNT(*) AS count_pid'))->groupBy('pid')->orderBy('count_pid', 'desc')->get();

Hasil dump untuk kedua kueri adalah sebagai berikut:

#attributes: array:2 [
  "pid" => "1271"
  "count_pid" => 19
],
#attributes: array:2 [
  "pid" => "1273"
  "count_pid" => 12
],
#attributes: array:2 [
  "pid" => "1275"
  "count_pid" => 7
]
jc_anchor
sumber
-2

Ini berfungsi untuk saya jadi Coba Ini: $ ad-> getcodes () -> different ('pid') -> count ()

Sushant Yadav
sumber
Hai, selamat datang di SO. Saat menjawab pertanyaan, harap berikan informasi tambahan tentang kode yang Anda berikan. Kontribusi seperti ini dipersilakan tetapi orang lain di masa mendatang mungkin mendapat manfaat dari penjelasan
singkat
-3

coba ini

$ad->getcodes()->groupby('pid')->distinct()->count('pid')
xiaoxiao
sumber