Laravel binding shows big number being applied to the query - php

I have a function that casts and returns the following:
$price = (double)number_format(2.97, 5, '.', '');
But when doing the query through Laravel Eloquent like:
$query = \App\Models\CustomersPrices::where('price', $price)->exists();
I wasn't finding the price in database. After some digging I did the following:
DB::enableQueryLog();
$query = \App\Models\CustomersPrices::where('price', $price)->exists();
$sql = DB::getQueryLog();
\Log::error($sql);
And the result is:
array (
0 =>
array (
'query' => 'select exists(select * from `customers_prices` where `price` = ? ) as `exists`',
'bindings' =>
array (
0 => 2.970000000000000195399252334027551114559173583984375,
),
'time' => 1.560000000000000053290705182007513940334320068359375,
),
)
Why is this happening? Doing var_dump($price) shows float(2.97).
What am I missing?

Solved.
Comparing as string didn't work https://i.postimg.cc/sD2DnDrm/wtf.png
The solution was to firstly cast the field into a string and then compare both values as string.
SELECT * FROM ... WHERE CAST(price AS CHAR(30)) = '2.97000';
https://i.postimg.cc/dwxcr9Lg/wtf2.png

Related

Laravel query builder returning empty where phpmyadmin returns results

I am trying to resolve an issue where using Laravel's query builder I am getting no results, but when I run the same query in php my admin i got result's..
This is the query:
DB::table('nm_product')->select(
DB::raw(
'IF(LOCATE(" ",pro_title,POSITION("'.$products
.'" IN pro_title))<>"0",SUBSTR(pro_title,POSITION("'.$products
.'" IN pro_title),LOCATE(" ",pro_title,POSITION("'.$products
.'" IN pro_title)) - POSITION("'.$products
.'" IN pro_title) ) , "aaa") as keyword'
),
'mc_name',
'pro_title'
)->join('nm_maincategory', 'mc_id', '=', 'pro_mc_id'
)->where(DB::raw('LOWER(pro_title)'),'like','"% '.$products.'%"'
)->orwhere(DB::raw('LOWER(pro_title)'),'like','"'.$products.'%"'
)->get();
You can see what the query is running, it is a way of testing processes:
#Last Query
\DB::enableQueryLog();
// code request
DB::table('nm_product')->select(...
$query = \DB::getQueryLog();
$lastQuery = end($query);
\Log::info(json_encode($lastQuery));
Example:
You get something like this
array:3 [
"query" => "select * from `table` where `table`.`id` = ?"
"bindings" => array:1 [▼
0 => 1
]
"time" => 0.5
]
And replacing the value of bindings in the query you could run the output directly to your database to see if the query is correct
Select * from `table` where `table`.`id` = 1
[1] => Array
(
[query] => select IF(LOCATE(" ",pro_title,POSITION("can" IN pro_title))"0",SUBSTR(pro_title,POSITION("can" IN pro_title),LOCATE(" ",pro_title,POSITION("can" IN pro_title)) - POSITION("can" IN pro_title) ) , "aaa") as keyword, `mc_name`, `pro_title` from `nm_product` inner join `nm_maincategory` on `mc_id` = `pro_mc_id` where LOWER(pro_title) like ? or LOWER(pro_title) like ?
[bindings] => Array
(
[0] => "% can%"
[1] => "can%"
)
[time] => 0.52
)
I replaced the variables and placed the query in phpmyadmin and i got this results
Display Image

How to Order a query

I have an array $sorted_array its value is
Array ( [0] => 3 [1] => 1 [2] => 6 )
Now based on the $sorted_array i created an array
$first_array = Yii::app()->db->createCommand()
->select('*')
->from('form_fields')
->where(array('not in', 'id', $sorted_array))
->andWhere('form_id=:form_id', array(':form_id'=>$form_id))
->queryAll();
$sorted_array value is the id (Primary key) of table form_fields.
When i run this query i get the array $first_array but not in the order in which i want it. ie, I will get an array in order $id=1,3,6.
Now my wanted order is 3,1,6 (exactly as $sorted_array). How can i get $first_array in that order?
You can do using ->order() Add order( 'id' ) to your code this way:
$first_array = Yii::app()->db->createCommand()
->select('*')
->from('form_fields')
->where(array('not in', 'id', $sorted_array))
->andWhere('form_id=:form_id', array(':form_id'=>$form_id))
->order('id')
->queryAll();
otherwise if is not possibile build the query you need with query builder you can use
Yii::app()->db->createCommand("select * from your_table")->queryAll();
and for binding param
Yii::app()->db->createCommand(
'select * from your_table where yuor_field =:your_param')->
bindValue('your_param',$yuor_value)->queryAll();
this returns all rows using a specified SQL statement
$sql = "select * from form_fields
where id not in (3,1,6)
and form_id = " . $form_id .
"order by field(id, 3,6,1);";
$first_array = Yii::app()->db->createCommand($sql)->queryAll();

Why laravel query doesn't return right result?

I have this code in laravel to get the products that will run out soon.
$productos = DB::table('productos')
->where('producto_minimo', '>=', 'producto_cantidad')
->get();
And what I get is the following result
which is not the right result. While in MySql I get the right results whith this query SELECT * FROM productos where producto_minimo >= producto_cantidad;
Update
The query log - DB::getQueryLog() - shows this
2 =>
array (size=3)
'query' => string 'select * from `productos` where `producto_minimo` >= ?' (length=54)
'bindings' =>
array (size=1)
0 => string 'producto_cantidad' (length=17)
'time' => float 1
I assume you've got to use the whereRaw method:
$productos = DB::table('productos')
->whereRaw('producto_minimo >= producto_cantidad')
->get();
Your query will compare the value in the column producto_minimo with the string 'producto_cantidad'
Have a look at Eloquents documentation of advanced wheres:
DB::table('users')
->whereExists(function($query)
{
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
The query above will produce the following SQL:
select * from users
where exists (
select 1 from orders where orders.user_id = users.id
)

insert multiple rows in a saveall in cakephp

i'm newbie in Cake and wodering how to insert multiple rows in a single saveall function,
i got this table,
CREATE TABLE IF NOT EXISTS `dates` (
`date` varchar(10) COLLATE utf8_unicode_ci NOT NULL
)
what i'm trying to do is let user select start date and end date using JQuery calander, once submit all the dates between this range will be saved into database, i already got the array of dates eg:
`array(
(int) 0 => '5/8/2013',
(int) 1 => '6/8/2013',
(int) 2 => '7/8/2013',
(int) 3 => '8/8/2013',
)
`
then my controller looks like this:
public function index(){
if ($this->request->is('post')) {
$this->Date->create();
$data = array();
$data['dates']=array();
$startDate = $this->request->data['Date']['from'];
$endDate = $this->request->data['Date']['to'];
$datesBlocked = $this->loopDates($this->request->data['Date']['from'],$this->request->data['Date']['to']);
$data['dates'][] = $this->request->data['Blockdate']['from'];
$data['dates'][] = $this->request->data['Blockdate']['to'];
/*foreach($datesBlocked as $data) {
$data['dates'][] = $data;
}*/
if($this->Date->saveAll($data)) {
$this->Session->setFlash(__('done'));
if ($this->Session->read('UserAuth.User.user_group_id') == 1) {
// $this->redirect("/manages");
}
}
}
public function loopDates($from,$to){
$blockdates = array();
$start = strtotime($from);
$end = strtotime($to);
debug($start);
$counter = 0;
for($t=$start;$t<=$end;$t+=86400) {
$d = getdate($t);
$blockdates[$counter++] = $d['mday'].'/'.$d['mon'].'/'.$d['year'];
}
debug($blockdates);
return $blockdates;
}
issue was i can't get foreach work, if i uncomment the foreach, i got error said Illegal string offset 'dates' , so i commented that and try to only add the start date and end date to the array to see if that works, then i got another error said.
`array(
'dates' => array(
(int) 0 => '08/05/2013',
(int) 1 => '09/05/2013'
)
)
`
Notice (8): Array to string conversion [CORE\Cake\Model\Datasource\DboSource.php, line 1005]Code
cuz i'm trying to insert 2 values into one field...i know it should be sth like
`array(
'dates' => array( (int) 0 => '08/05/2013',
)
'dates' => array((int) 1 => '09/05/2013'
))
`but can't figure out how to do it. Any help would be much appreciate!!!!
The structure you'll want your array to save multiple dates using saveAll() is this:
array(
'Date' => array(
0 => array(
'date' => '08/05/2013',
),
1 => array(
'date' => '09/05/2013',
)
),
)
I know that this is a little late, but to write multiple rows in a loop, you have to proceed the save with a create().
eg:
foreach($items as $lineItem){
$this->Invoice->create();
$this->Invoice->save(array(
'user_id'=>$property['User']['id'],
'invoice_id'=>$invId['Invoices']['id'],
'item_id'=>$lineItem['item_number'],
'quantity'=>$lineItem['quantity'],
'price'=>$lineItem['mc_gross']
);
}
Just thought it was worth mentioning, hopefully it will help someone.

Zend subquery arguments

The query below represents what I am trying to do, I need to pull in a list of blog_posts and also join with a users table.
What it is also doing is pulling in a random 'picture_filename' from blog_updates_pictures. It needs blog_updates as a join to reference the blog_update_id.
What I'd like to do now is also COUNT the number of blog_updates for each blog_post. I think this is a subquery but every implementation fails. It would also be good to have the count accept arguments (ie. blog_updates where date = ?). Also, there may be no updates or pictures to a blog_post.
$select = $db->select ();
$select->from ( array ('b' => 'blog_posts' ), array('headline', 'date_created'));
$select->join ( array ('u' => 'users' ), 'u.user_id = b.user_id', array ( 'email' ) );
$select->joinLeft ( array ('bu' => 'blog_updates' ), 'bu.blog_id = b.blog_id', array () );
$select->joinLeft ( array ('bup' => 'blog_updates_pictures' ), 'bu.blog_update_id = bup.blog_update_id', array ('picture_filename' ) );
Can someone show me the way?
Thanks
What I'd like to do now is also COUNT the number of blog_updates for each blog_post.
You can achieve that using aggregation - use GROUP BY bu.blog_id, and as additional column COUNT(bu.blog_id) AS blog_updates_count. It should work.
Create subselects as:
$subselect = $db->select()
->from(
array ('bu' => 'blog_updates' ),
array(
'blog_id',
'updates' => 'count(*)'
)
)
->group("bu.blog_id");
And then join the $subselect with your main $select as:
$select->join(
array( 't' => $subselect),
"t.blog_id = b.blog_id",
array( 'updates' )
);
If we had the table structure you might get a more complete answer

Categories