Laravel error when get data from mySQL using groupBy - laravel

I want to get Data from mySQL where its only get 1 id_product,so when there is 2 data with same id_product value.. its only get the first one.I have tried the query in mySQL and its work, the query is like this
select `product_photo`.*, `product`.`id_merchant` from `product_photo` inner join `product` on
`product_photo`.`id_product` = `product`.`id` where `product`.`id_merchant` = 11 group by
`product_photo`.`id_product`
but i got error when i implemented it to my laravel controller,the code is like this
$id_merchant = $request->input('id_merchant');
$photo=DB::table('product_photo')
->join('product','product_photo.id_product','=','product.id')
->select('product_photo.*','product.id_merchant')
->where('product.id_merchant','=',$id_merchant)
->groupBy('product_photo.id_product')
->get();
return response()->json(['success'=>true,'message'=>'success', 'data' => $photo],200);
Can someone tell me why my laravel got error ? Sorry my english

This is caused by MySQL's strict mode. Change strict to false in your config/database.php file.
When you open the file, in the mysql array, set strict => false. After you disable MySQL's strict mode it shouldn't show the error anymore.

Related

create a sql view in laravel and convert a legacy sql query to new synthax

i got a form and i need to connect two tables and get the sum of one value of the two tables and display it in a mysql view. i saw in a sql legacy to laravel sql converter that i should use sum between '' , if i dont do it the values are not well summed, and if i use them it gives synthax error, how to do it well?
->with([
'form' => DB::table('form')
->select('repair.valor', DB::raw("'SUM'(valor) as totalValor"))
->join('repair','form.carPlate','=','repair.carPlate')
->get()
]);
}

Laravel Query Binding Reuse

Hi on Laravel 7 with sqldrv driver.
I have a large query and i use a lot of bindings, some the same multiples times in query like ids and stamps.
Example :
$query=... var = :id ... INSERT INTO ... foo = :i ... WHERE toni = :i ... "; $bindings =["id" => 123];
When i tried do run the query DB::statement($query, $bindings);, i get this error : Illuminate\Database\QueryException: SQLSTATE[07002]: [Microsoft][ODBC Driver 17 for SQL Server]COUNT field incorrect or syntax error (SQL:
I read that i can add in config\database.php 'options' => [ PDO::ATTR_EMULATE_PREPARES => true, ], but it not work, maybe because it's sqlsrv driver.
I could also declare and set variable in the header of the SQL queries, but i think it's an effort that is unnecessary.
Is there anyway to reuse bindings
I solve the question using SQL Variables, I declare them on top and use it everywhere on the query. So i use only one binding per variable.
DECLARE #cBOstamp as varchar(25) = :bostamp
The only problem i see on this, is variable declaration type. You must always type your variables.

laravel unique() dont work with paginating

i'm facing with an issue in laravel 5.7.28, i'm trying to get records with all of my fields and paginate them , sadly i got a bug in my code that cause registering users with duplicate phone number(a user registered itself more than one time and of course i fix the bug ) , for now i'm facing with a scenario that i want to fetch my (non-duplicate) distinct users on their phone, and paginate them . here is wishful scenario :
$users = User::distinct('phone')
->doesntHave('carrierUsers')
->doesntHave('thirdparty')
->latest()->paginate(40);
it returns all users (with duplicate phone number), seems distinct function not affected , so i tried unique function :
$users = User::doesntHave('carrierUsers')
->doesntHave('thirdparty')
->latest()->paginate(40)->unique('phone');
it works (for getting non-duplicate) but break paginating functionality
and for
$users = User::doesntHave('carrierUsers')
->doesntHave('thirdparty')
->latest()
->unique('phone')
->paginate(40);
i got error for undefined function on builder , means it works on collections ,
also i tried groupBy (search whole the web for solution) , it makes me confused till when i use it
User::doesntHave('carrierUsers')->doesntHave('thirdparty')
->latest()->groupBy('phone')
->paginate(40);
i got SELECT list is not in GROUP BY clause, is that mean in every phrase in my select statement (for now is all ('*') ) i should use it in my groupBy ?
i mean i need all columns , how can i have all those column in groupBy clause ? whats that mean by the way ?
, error is telling : this is incompatible with sql_mode=only_full_group_by. is she making this happen ? how can i fix it ?
1) excuse me for my english
2) Thanks for reading whole this
3) pleasure to reply and help me
Problem 1: Use distinct
For distinct() method, passing parameters is not supporteds, so distinct(phone) will not works.
You can use ->select('phone')->distinct() instead. However, support unique column is selected.
Problem 2: Use Group By
So if you want to select all columns and unique one column, you can use group by.
And because you are using mysql 5.7+.
The ONLY_FULL_GROUP_BY and STRICT_TRANS_TABLES modes were added in MySQL 5.7.5.
So if you select all columns and group one column, you will get the only_full_group_by error.
There are two options can solve this problem.
Solution1:
Use ANY_VALUE()
User::doesntHave('carrierUsers')->doesntHave('thirdparty')
->latest()
->selectRaw('phone, ANY_VALUE(id) AS id, ANY_VALUE(username) AS username, ...')
->groupBy('phone')
->paginate(40);
Solution2:
In config/database.php configuration, set strict mode to false(This is not very safty):
'mysql' => [
'driver' => 'mysql',
...
'strict' => false,
],

Laravel Query Result Issue: query is returning empty array even there is data exist into database

I am working on laravel 5.4. I am trying to get data from database using below query:
$obj = \Illuminate\Support\Facades\DB::table('A')
->join('B', 'A.Intake', '=', 'B.Id')
->join('C', 'B.StreamId', '=', 'C.StreamId')
->select(\Illuminate\Support\Facades\DB::raw('DISTINCT(C.StreamId) As StreamId'))
->where('A.YearId', $yearId);
$streamIds = $obj->get()->toArray();
The above query is returning empty results. I have also debug the query generated by laravel. Below is the raw query generating by laravel on the basis of above conditions:
select DISTINCT(C.StreamId) As StreamId from A
inner join B on A.Intake = B.CentreStreamId
inner join C on B.StreamId = C.StreamId
where A.YearId = '12'
When I run the above raw query directly in my database, then it returns me some records. But when I try to get records in laravel then it returns me empty results.
I am not able to get the issue with the above query. Can someone please tell me why it is returning empty results set? If there is any issue with above query builder syntax then please correct my query.
Thanks in Advance.

Binding on `statement` not supported in Eloquent 5.1?

I'm new to Laravel and trying to do a string query in Eloquent. I was trying to use DB::statement, but I kept getting errors about placeholders in the query string. It seems I either don't have the syntax right, or bindings are unimplemented or unsupported?
The reason I want to use statement is because I'm doing an INSERT... SELECT, which I haven't been able to find any documentation about in Eloquent.
Here's my code:
$ php artisan tinker
Psy Shell v0.5.2 (PHP 5.6.13-0+deb8u1 — cli) by Justin Hileman
>>> echo \DB::statement('CREATE DATABASE :db', [':db'=>'test']);
Illuminate\Database\QueryException with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1 (SQL: CREATE DATABASE :db)'
>>> \DB::statement('CREATE DATABASE ?', ['test']);
Illuminate\Database\QueryException with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1 (SQL: CREATE DATABASE test)'
These are the two syntax forms (? and :string) from PDO. Other methods in DB such as select and insert support this, according to the documentation.
The relevant parts of these errors are near '?' at line 1 (SQL: CREATE DATABASE :db) and near '?' at line 1 (SQL: CREATE DATABASE test). MySQL thinks there is an unbound ? in the query string. I didn't even use that syntax in the first query. I'm concluding from that that the bind() method did not correctly bind my placeholders.
This question on Laracasts is asking about the syntax, but there is no accepted answer.
Edit One answer says that statement() doesn't support CREATE. I tried some queries out with SELECT, and got the same results, with both placeholders:
>>> \DB::statement('SELECT 1 WHERE \'a\' = ?', array('a'));
Illuminate\Database\QueryException with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE 'a' = ?' at line 1 (SQL: SELECT 1 WHERE 'a' = a)'
>>> \DB::statement('SELECT 1 WHERE \'a\' = :letter', array(':letter'=>'a'));
Illuminate\Database\QueryException with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE 'a' = ?' at line 1 (SQL: SELECT 1 WHERE 'a' = :letter)'
Actually, you can use create and drop query in DB::statement(), but named bindings is not used in that way.
Here are some queries that will success.
drop and create do not accept bindings.
>>> \Db::statement('create database test')
=> true
>>> \Db::statement('drop database test')
=> true
Do not use backslash and single quotes in the statement
>>> \Db::statement('insert into users (id, name) values (?, ?)', ['1', 'John'])
=> true
DB::statement() only return ture when success, so if you want to see select results, you should use DB::select()
>>> \Db::statement('select * from users')
=> true
>>> \Db::select('select * from users')
=> [
{#770
+"id": 1,
+"name": "John",
},
]
Remove leading : in the second argument.
>>> \Db::statement('update users set name = :name where id = :id', ['id' => 1, 'name' => 'John'])
=> true
You will get affect rows if you use DB::update and DB::delete
>>> \Db::delete('delete from users where id = :id', ['id' => 1])
=> 1
The errors you receive are only indirectly related with Laravels DB::statement() function. They all fail within that method at the line
return $me->getPdo()->prepare($query)->execute($bindings);
within the file vendor/laravel/framework/src/Illuminate/Database/Connection.php
Responsible for that failure is the resulting call to PDO::prepare()
The Docuemenation says:
Parameter markers can represent a complete data literal only. Neither part of literal, nor keyword, nor identifier, nor whatever arbitrary query part can be bound using parameters. For example, you cannot bind multiple values to a single parameter in the IN() clause of an SQL statement.
Also have a look at the user contributed notes at the above php.net documentation. Additionally have a look at Can PHP PDO Statements accept the table or column name as parameter?
Your create examples are not supported by PDO.
The reason your SELECT examples fail is simply due to an invalid syntax.
\DB::statement('SELECT 1 WHERE \'a\' = ?', array('a'))
You are simply missing the FROM clause. This example works perfeclty well at my test computer:
$ret = \DB::statement('SELECT 1 FROM `users` WHERE `username` = ?', ["gregor"]);
But
$ret = \DB::statement('SELECT 1 WHERE `username` = ?', ["testname"]);
Generates the exact error, you receive.
Also note, that \DB::statement does not return any ressources. It just indicates by returning true or false, whether the query suceeded.
Your option is to use DB::raw() within your insert() statement, if you want to use INSERT...SELECT. Some googling will help you, to find the proper solution. Maybe as Starting Points: Raw Queries in Laravel, or How to use raw queries in Laravel
What you're trying to do is passing the table name through binding.
DB::statement('select * from ?',['users'])
which according to this post, it's not possible.
of course if you want to sanitize the data you can use an array of short codes like so:
$tables = ['users','test','another'];
and the query would look something like:
$code = 0;
DB::statement("select * from $tables[$code] where a=?",[2]);
DB::statement("create table $tables[$code]");

Resources