Laravel Eloquent - diff () và count () không hoạt động bình thường cùng nhau


95

Vì vậy, tôi đang cố gắng lấy số lượng pids riêng biệt trên một truy vấn, nhưng giá trị trả về bị sai.

Đây là những gì tôi cố gắng làm:

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

thứ trả về giá trị "2", trong khi giá trị mà nó phải trả về, phải là "1".

Để giải quyết vấn đề, tôi đang làm điều này:

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

những gì hoạt động tốt và trả về "1"

Có quy tắc nào mà số đếm và số lượng riêng biệt không thể có trên cùng một truy vấn không? Tôi thấy cách giải quyết khác là "nặng", tôi muốn làm cho truy vấn ban đầu hoạt động :(


Bạn có gì trong bảng mẫu trong cơ sở dữ liệu? Và bạn muốn đạt được điều gì? Bây giờ bạn có thể sẽ nhận được số giá trị khác biệt trong pidcột, vì vậy nếu bạn có trong hồ sơ bảng 2 của bạn - một với pid 1, thứ hai với pid 2, số lượng phải trả lại 2.
Marcin Nabiałek

bạn có thể đơn giản thay thế get bằng count theo cách này: $count = DB::table('tablename')->count(DB::raw('DISTINCT pid')); also can do: DB::table('tablename')->distinct('pid')->count('pid');
bharat

Câu trả lời:


123

Những điều sau đây sẽ hoạt động

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

2
Đã gặp vấn đề tương tự và có vẻ như chỉ là bỏ qua groupBymẹo nhỏ.
jeteon

8
Distinction không có bất kỳ đối số nào. Gọi riêng biệt () khi xây dựng truy vấn của bạn chỉ đặt boolean được bảo vệ thành true, đối số bị bỏ qua.
Matt McDonald

Trên L5.1 và điều này vẫn không hoạt động. Sử dụng count()dường như để tắt hoặc bỏ distinct(). Sử dụng groupBy()như mô tả trong suốt câu hỏi. Chỉnh sửa: Tôi tìm thấy chẵn groupBy()đang cung cấp một sự khác biệt count()so với get()theo sau bằng cách đếm mảng kết quả.
Jason

@Jason Tôi cũng quan sát như bạn. Xem câu trả lời của tôi để có giải pháp.
Zoon

21
Các distinct()chức năng không có đối số. Bạn có thể thay đổi nó thành $ad->getcodes()->distinct()->count('pid');với cùng một kết quả.
Trevor Gehman

26

Một câu trả lời chung chung hơn sẽ giúp tôi tiết kiệm thời gian và hy vọng những người khác:

Không hoạt động (trả về tổng số tất cả các hàng):

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

Cách khắc phục:

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

17

Bất kỳ ai khác xem qua bài đăng này và không tìm thấy các đề xuất khác để hoạt động?

Tùy thuộc vào truy vấn cụ thể, có thể cần một cách tiếp cận khác. Trong trường hợp của tôi, tôi cần đếm kết quả của a GROUP BY, ví dụ:

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

hoặc sử dụng COUNT(DISTINCT b):

SELECT COUNT(DISTINCT b) FROM a

Sau một số phân vân xung quanh, tôi nhận ra rằng không có chức năng Laravel tích hợp sẵn cho một trong hai chức năng này. Vì vậy, giải pháp đơn giản nhất là sử dụng sử dụng DB::rawvới các countphương pháp.

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

Hãy nhớ, không sử dụng groupBytrước khi gọi count. Bạn có thể áp dụng groupBysau, nếu bạn cần để lấy hàng.


$ Builder đến từ đâu?
Andrew

1
@Andrew Trình tạo truy vấn Laravel mà bạn đang sử dụng cho truy vấn. Ví dụ: một đối tượng Eloquent$books = Book::where(...)->count(...)
Zoon

->count(DB::raw('DISTINCT b'))tạo cùng một truy vấn SQL như->distinct()->count('b')
Trevor Gehman

5

Tôi đã gặp vấn đề tương tự và đã tìm ra cách khắc phục nó.

Vấn đề là cách trình tạo truy vấn của Laravel xử lý các tập hợp. Nó nhận kết quả đầu tiên được trả về và sau đó trả về giá trị 'tổng hợp'. Điều này thường ổn, nhưng khi bạn kết hợp số lượng với nhóm Do bạn đang trả về số lượng cho mỗi mục được nhóm. Vì vậy, tổng của hàng đầu tiên chỉ là số lượng của nhóm đầu tiên (vì vậy có thể có thứ gì đó thấp như 1 hoặc 2).

Vì vậy, số lượng của Laravel đã hết, nhưng tôi đã kết hợp trình tạo truy vấn Laravel với một số SQL thô để có được số lượng chính xác các kết quả được nhóm của tôi.

Đối với ví dụ của bạn, tôi hy vọng những điều sau sẽ hiệu quả (và để bạn tránh mắc phải):

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

Nếu bạn muốn đảm bảo rằng bạn không mất thời gian chọn tất cả các cột, bạn có thể tránh điều đó khi tạo truy vấn của mình:

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

4

Tôi đã gặp cùng một vấn đề.

Nếu bạn cài đặt thanh gỡ lỗi laravel, bạn có thể thấy các truy vấn và thường thấy sự cố

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

thay đổi thành

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

Bạn cần đặt các giá trị để trả về là riêng biệt. Nếu bạn không đặt các trường chọn, nó sẽ trả về tất cả các cột trong cơ sở dữ liệu và tất cả sẽ là duy nhất. Vì vậy, hãy đặt truy vấn thành khác biệt và chỉ chọn các cột tạo nên giá trị 'riêng biệt' mà bạn có thể muốn thêm vào. ->select('pid','date')để nhận tất cả các giá trị duy nhất cho người dùng trong một ngày


4

Bạn có thể sử dụng cách sau để lấy dữ liệu duy nhất theo nhu cầu của bạn như sau,

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

$count = $data->count();

Hy vọng điều này sẽ hiệu quả.


1

Điều này sẽ không hoạt động?

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

Xem tại đây để thảo luận ..


3
Đây không phải là một giải pháp tốt, vì lệnh get()gọi sẽ thực hiện truy vấn và trả về kết quả từ cơ sở dữ liệu, sau đó count()chạy trên Bộ sưu tập.
Trevor Gehman

1
$solution = $query->distinct()
            ->groupBy
            (
                [
                    'array',
                    'of',
                    'columns',
                ]
            )
            ->addSelect(
                [
                    'columns',
                    'from',
                    'the',
                    'groupby',
                ]
            )
            ->get();

Hãy nhớ rằng nhóm theo là tùy chọn, điều này sẽ hoạt động trong hầu hết các trường hợp khi bạn muốn một nhóm đếm theo để loại trừ các giá trị được chọn trùng lặp, addSelect là một phương thức phiên bản của trình tạo truy vấn.


0

Distinction không nhận đối số vì nó thêm DISTINCT trong truy vấn sql của bạn, tuy nhiên, bạn CÓ THỂ cần xác định tên cột mà bạn muốn chọn riêng biệt. Do đó, nếu bạn có Flight->select('project_id')->distinct()->get()là bằng SELECT DISTINCT 'project_id' FROM flightsvà bây giờ bạn có thể thêm các từ bổ nghĩa khác như count () hoặc thậm chí là các truy vấn hùng hồn thô.


0

Dựa trên tài liệu Laravel cho các truy vấn thô, tôi có thể đếm được trường được chọn để làm việc với mã này trong mô hình sản phẩm.

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

Mặt tiền này đã hoạt động để có được kết quả tương tự trong bộ điều khiển:

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

Kết quả kết xuất cho cả hai truy vấn như sau:

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

-1

Điều này đã làm việc cho tôi, vì vậy hãy thử Cách này: $ ad-> getcodes () -> difference ('pid') -> count ()


Chào mừng đến với SO. Khi trả lời một câu hỏi, vui lòng cung cấp thêm thông tin về mã bạn cung cấp. Những đóng góp như thế này được hoan nghênh nhưng những người khác trong tương lai có thể được hưởng lợi từ lời giải thích
ngắn gọn

-3

thử cái này

$ad->getcodes()->groupby('pid')->distinct()->count('pid')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.