دستور GROUP BY در لاراول 5 و 6 کار نمیکنه

- 1 هفته پیش
توسط سعید محمدی آپدیت شد
سعید محمدی ( 1140 تجربه )
2 هفته پیش

سلام من از GROUP BY در لاراول 5.6 استفاده میکنم بصورت زیر :

return DB::table('statistics')->select('*')->groupBy('persian_date')->get();

ولی اخطار زیر رو نشون میده متوجه نشدم

SQLSTATE[42000]: Syntax error or access violation: 
1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column id which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by 
SQL: select * from statistics group by persian_date
بهترین پاسخ انتخاب شده توسط سعید محمدی
سعید محمدی
1 هفته پیش

بالاخره تونستم درستش کنم که تو یه جایی خیلی درست توضیح داده بود میزارم لینکش و که اگه کسی همچین مشکلی داشت زود حلش کنه

http://selimreza.com/laravel-group-by-clause-and-contains-nonaggregated-column/

توی لینکی که گذاشتم میگه باید برید تو قسمت
config\database.php
و
اگه ار لارول 5.6 استفاده میکنید باید strict رو پیدا کنید و مقدارش رو false قرار بدید و برای لارول 5.7 هم همون مقدار پیش فرض باید باشه یعنی true که فکر میکنم برای ورژن های بالاتر از 5.6 باید مقدار true باشد.

بصورت کلی اینه :

'mysql' => [        
    'strict' => false, //behave like 5.6        
   //'strict' => true //behave like 5.7 or above    ],
پایان جهان ( 71428 تجربه )
2 هفته پیش
تخصص : بیکار برنامه نویس

درود...
نحوه استفاده از Group By در لاراول 6
پیوند های زیر:
https://laravel.com/docs/6.x/queries
https://stackoverflow.com/questions/18533080/laravel-eloquent-groupby-and-also-return-count-of-each-group

علی بیات ( 192597 تجربه )
2 هفته پیش
تخصص : توسعه دهنده ارشد وب

درود

شما ابتدا باید نتایج رو دریافت کنید (با استفاده از get ) و بعدش توسط groupBy مرتبشون کنید و نه بر عکس
کوئری رو به شکل زیر تغییر بدید مشکل حل میشه:

DB::table('statistics')
    ->select('*')
    ->get()
    ->groupBy('persian_date');

موفق باشید.

سعید محمدی ( 1140 تجربه )
1 هفته پیش

@ali.bayat
ممنونم اینی که گفتید درست کار میکنه

DB::table('statistics')->select('*')->get()->groupBy('persian_date');

ولی به این شکل

DB::table('statistics')->select('id','persian_date',DB::raw('SUM(page_view) as visit'))->get()->groupBy('persian_date');

یا این شکل

DB::table('statistics')->select('id','persian_date')->get()->orderBy('id', 'desc')->groupBy('persian_date');

کار نمیکنه و همون اخطار و میده
یعنی با وقتی

->select('id','persian_date',DB::raw('SUM(page_view) as visit'))

و یا

->orderBy('id', 'desc')

اضافه میشه کار نمیکنه

و اینکه من بر اساس مستندات خود لاروال 5.6 انجام میدم

$users = DB::table('users') ->select(DB::raw('count(*) as user_count, status')) ->where('status', '<>', 1) ->groupBy('status') ->get();

https://laravel.com/docs/5.6/queries#raw-expressions

ولی کار نکرد که شما گفتید جای get() رو تغییر بدم که کار کرد واقعا برام جالب بود اون قسمتش

سعید محمدی ( 1140 تجربه )
1 هفته پیش

..........

علی بیات ( 192597 تجربه )
1 هفته پیش
تخصص : توسعه دهنده ارشد وب

درود

ببینید متد‌ها در کوئری بیلدر باید به ترتیب خاصی اجرا بشند
برای مثال اگر شما می‌خواهید از متدهای orderBy و groupBy با هم در یک کوئری استفاده کنید; دقت کنید که متد orderBy قبل از get و متد groupBy باید بعد از get قرار بگیره. مثل زیر:

DB::table('statistics')      // استفاده از جدول موردنظر 
    ->select('*')               //  انتخاب تمام فیلدها
    ->orderBy('id', 'desc')     //  سورت کردن نتایج 
    ->get()                     //  دریافت نتایج 
    ->groupBy('persian_date');  //  دسته بندی نتایج دریافتی 
سعید محمدی ( 1140 تجربه )
1 هفته پیش

@ali.bayat

این نوع انتخاب کار نمیکنه

>select('id','persian_date',DB::raw('SUM(page_view) as visit

وقتی ترکیب انتخاب ستون id و persian_date در کنار

',DB::raw('SUM(page_view) as visit

قرار میگیره

علی بیات ( 192597 تجربه )
1 هفته پیش
تخصص : توسعه دهنده ارشد وب

بعضی کوئری ها در کوئری بیلدر لاراول یا الکوئنت ممکنه کمی پیچیده بشند.. اگر به چنین حالتی رسیدید کلا از DB::raw استفاده کنید و کوئری SQL خام رو بهش پاس بدید فقط باید مراقب مسائلی مثل SQL Injection باشید..

متدهای الکوئنت و کوئری بیلدر رو بیشتر مطالعه کنید. حتما گزینه مورد نظر رو پیدا می‌کنید

سعید محمدی ( 1140 تجربه )
1 هفته پیش

@ali.bayat
دوست عزیزم اینهایی ک میگین و میدونم
میگم چرا تو قسمت select وقتی sum رو استفاده میکنم اخطار میده

علی بیات ( 192597 تجربه )
1 هفته پیش
تخصص : توسعه دهنده ارشد وب

اولا متن ارور رو بگذارید ..
جایگزین DB::raw ... متد selectRaw هست. چنانچه با اون متد هم به خطا می‌خورید مشکل از کدتونه

سعید محمدی ( 1140 تجربه )
1 هفته پیش

@ali.bayat
ببینید دوست عزیزم حرفای شما درست ولی من بر اساس خود داکیومنت لاراول5.6 نوشتم که تو این آدرس میتونید مشاهده کنید:
https://laravel.com/docs/5.6/queries#raw-expressions
که تو مستندات کد نوشته شده توسط لاروال 5.6 به صورت زیر هست :

$users = DB::table('users')
                     ->select(DB::raw('count(*) as user_count, status'))
                     ->where('status', '<>', 1)
                     ->groupBy('status')
                     ->get();

کدی که من نوشتم به این صورت هست که قبلا در لاراول 5.2 نوشته بودم و بدون هیچ مشکلی کار میکرد و دقیقا مثل مستندات لاراول بود و کار میکرد ولی الان تو لاروال 5.6 کار نمیکنه این کد من هست:

        $result = DB::table('statistics')
            ->select(DB::raw('SUM(page_view) as total_visit, persian_date, ip'))
            ->whereNotNull('ip')
            ->groupBy('persian_date')
            ->get();

و اخطاری هم که صادر میشه بصورت زیر هست :

C:\wamp\www\mysite\vendor\laravel\framework\src\Illuminate\Database\Connection.php
     * @param  array     $bindings
     * @param  \Closure  $callback
     * @return mixed
     *
     * @throws \Illuminate\Database\QueryException
     */
    protected function runQueryCallback($query, $bindings, Closure $callback)
    {
        // To execute the statement, we'll simply call the callback, which will actually
        // run the SQL against the PDO connection. Then we can calculate the time it
        // took to execute and log the query SQL, bindings and time in our memory.
        try {
            $result = $callback($query, $bindings);
        }

        // If an exception occurs when attempting to run a query, we'll format the error
        // message to include the bindings with SQL, which will make this exception a
        // lot more helpful to the developer instead of just the database's errors.
        catch (Exception $e) {
            throw new QueryException(
                $query, $this->prepareBindings($bindings), $e
            );
        }

        return $result;
    }

    /**
     * Log a query in the connection's query log.
     *
     * @param  string  $query
     * @param  array   $bindings
     * @param  float|null  $time
     * @return void
     */
    public function logQuery($query, $bindings, $time = null)
    {
        $this->event(new QueryExecuted($query, $bindings, $time, $this));

        if ($this->loggingQueries) {
Arguments
"SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mydb.statistics.ip' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by (SQL: select SUM(page_view) as total_visit, persian_date, ip from `statistics` where `ip` is not null group by `persian_date`) ◀"

تو github هم گفته بودن تو تنظیمات phpmyadmin و بخش variables مقدار مربوط به sql mode را خالی کنم که اونم کار نکرد
اینم لینکش
https://github.com/coral-erm/coral/issues/445

در حالی که این کد کار میکنه :

        $result = DB::table('statistics')
            ->select(DB::raw('SUM(page_view) as total_visit, persian_date'))
            ->groupBy('persian_date')
            ->orderBy('persian_date', 'asc')
            ->take(30)
            ->get();

انگار میگه فقط ستون هایی که تو قسمت groupBy, هست و یا بصورت raw-expressions هست رو واکشی میکنه واقعا نمیدونم چیکار کنم

امیدوارم شما و یا مهندس موسوی @hesammousavi راهنمایی کننند درست شه.

سپاس

سعید محمدی ( 1140 تجربه )
1 هفته پیش

بالاخره تونستم درستش کنم که تو یه جایی خیلی درست توضیح داده بود میزارم لینکش و که اگه کسی همچین مشکلی داشت زود حلش کنه

http://selimreza.com/laravel-group-by-clause-and-contains-nonaggregated-column/

توی لینکی که گذاشتم میگه باید برید تو قسمت
config\database.php
و
اگه ار لارول 5.6 استفاده میکنید باید strict رو پیدا کنید و مقدارش رو false قرار بدید و برای لارول 5.7 هم همون مقدار پیش فرض باید باشه یعنی true که فکر میکنم برای ورژن های بالاتر از 5.6 باید مقدار true باشد.

بصورت کلی اینه :

'mysql' => [        
    'strict' => false, //behave like 5.6        
   //'strict' => true //behave like 5.7 or above    ],
برای ارسال پاسخ باید وارد سایت شوید