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();
Related
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
I have 2 tables. The first table is an equipment table. A query from this table looks like this:
id name user_id
-----------------------
1 equip1 1001
2 equip2 1002
The seconde table is an users table. A query from this table looks like this:
id username
--------------
1001 user1
1002 user2
I want to achieve something like this:
id name user_id username
-----------------------------------
1 equip1 1001 user1
2 equip2 1002 user2
Is there a way to join both arrays like doing a join query? I can't use JOIN in my query, because the tables are on different databases (I know there is a way to do JOIN on different databases, but I'm not allowed to use that).
EDIT:
I'm adding the structure of these arrays.
$equipment = array(
[0] => array(
['id'] => 1,
['name'] => 'equip1',
['user_id'] => 1001
),
[1] => array(
['id'] => 2,
['name'] => 'equip2',
['user_id'] => 1002
)
);
$users= array(
[0] => array(
['id'] => 1001,
['username'] => 'user1'
),
[1] => array(
['id'] => 1002,
['username'] => 'user2'
)
);
You would likely have to join the queries yourself. I don't believe there is a built in function (not counting walk or map with a callback). This is what I would do
//empty array for indexing users under their id for faster loopups
$users = array();
//loop over the users result
foreach($usersResult as $row){
//index users under their id.
$users[$row['id']] = $row['username'];
}
//now loop over the equipment to join the arrays together
foreach($equipmentResult as $key=>$row){
//add the username column
$row['username'] = isset($users[$row['user_id']])?$users[$row['user_id']]:null;
//save back into the equipment row
$equipmentResult[$key] = $row;
}
//display
print_r($equipmentResult);
This could easily be turned into a function where you pass arguments that would build the "ON" portion for the column names.
Edit: Made it a function.
<?php
/**
* Joins two arrays as if they were joined in a query
* #param Array $arrayA The base (left) array to join into
* #param Array $arrayB The right array to join into A
* #param String $colA The column name to join on for arrayA
* #param String $colB [optional] The column name to join on for arrayB. If
* blank, then it is assumed the same column name as colA
* #param boolean $leftJoin [optional] Should this be a left join and include rows
* from A where no value exists in B?
* #return void
*/
function array_join($arrayA, $arrayB, $colA, $colB=null, $leftJoin=false){
//if no value was passed for colB, assume it is the same value as colA
if(is_null($colB)){
$colB = $colA;
}
//output data
$out = array();
//create an index for array B for faster lookups
$idxB = array();
$colsB = array();
foreach($arrayB as $row){
//get the value from B
$valB = $row[$colB];
//if the column doesn't exist in the index, add it
if(!isset($idxB[$colB])){
$idxB[$colB] = array();
}
//index the value
$idxB[$valB][] = $row;
//store the known column to an array for use below
if(empty($colsB)){
$colsB = array_keys($row);
}
}
//loop over array A
foreach($arrayA as $rowA){
//get the value for the column
$valA = $rowA[$colA];
//does the value from A exist in B
$rowB = isset($idxB[$valA])?$idxB[$valA]:null;
//join the rows
//add blank columns if left join
if($leftJoin && is_null($rowB)){
$rowBJoin = array_combine($colsB, array_fill(0, count($colsB), null));
//add the row to our output
$out[] = $rowA + $rowBJoin;
} else {
//inner join or value is not null
//loop over all the rows from the B index that we are joining on
foreach($rowB as $rowBJoin){
//add the row to our output
$out[] = $rowA + $rowBJoin;
}
}
}
return $out;
}
How to achieve this query in phalcon using query builder (best method):
$results = "select * from table where name like 'A%' limit 10"; // <-- 10 records
$total = "select count(1) from table where name like 'A%'"; // <-- 100 records
return [
'data' => $result,
'total' => $total
];
im extjs user and i need to get total over limit to display paging information (eq: displaying 1 to 10 from 100 records)
thx.
You can achieve this with Pagination, see here: Pagination Docs
Only thing is to use QueryBuilder adapter. But this can be done with:
$builder = $this->modelsManager->createBuilder()
->from('Table')
->andWhere('name like :name:', array('name' => 'A%' ) );
$paginator = new Phalcon\Paginator\Adapter\QueryBuilder(array(
"builder" => $builder,
"limit"=> 10,
"page" => 1
));
return [
'data' => $paginator->items,
'total' => $paginator->total_items
];
I'm trying to use Group by in find method for my relational database I want to get the latest record with unique receiver_id out of result set filtered by user_id and below is my code:
$this->loadModel('Chat');
$lastChat = $this->Chat->find('all', array(
'conditions' => array(
'Chat.user_id' => $user_id['User']['id']
),
'fields' => array(
'Chat.id',
'Chat.chat',
'Chat.user_id',
'Chat.receiver_id',
'Chat.read',
'Chat.created'
),
'group' => array('Chat.receiver_id'),
'order' => array('Chat.created DESC')
));
However, this does not seem to work. I'm not sure why but I'm only getting one result...
How can I get multiple results with rules based on above.
Try the following:
$db = $this->Chat->getDataSource();
$chats = $db->query("SELECT * , (Chat.user_id + Chat.receiver_id) AS dist
FROM (
SELECT *
FROM chats t
WHERE ( t.user_id =$id OR t.receiver_id =$id )
ORDER BY t.id DESC
) Chat
GROUP BY dist
ORDER BY Chat.id DESC");
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