Yii2 Matching all values in IN clause - mysql

Im trying to get a query which matches all values within an IN clause. This is what I have right now in UsersSearch.php model:
$categoryIdsMatching = UsersCategoriesAssn::find()
->select('userID')
->distinct(true)
->joinWith('userCategory')
->andWhere(['IN', 'usersCategories.id', $this->catNameSearch])
->column();
$query->andWhere(['userID'=>$categoryIdsMatching]);
But it gets records matching at least one of the values... How can I set that andWhere clause to match all values instead of some of them?

This could be something similiar to:
$categoryIdsMatching = UsersCategoriesAssn::find()
->select('userID')
->distinct(true)
->joinWith('userCategory')
->andWhere(['IN', 'usersCategories.id', $this->catNameSearch])
->groupBy('userTable.userID')
->having('COUNT(userTable.userID) ='.count($this->catNameSearch));
There is propably no other way to filter IN operator to match all values in MySQL.

Yii2 where in clause
Model :
//GET MULTIPLE AREA
public function getAreaSelected() {
//GET SAVE COMMA SEPERARED VALUE CONVERT IN TO ARRAY
$areaArray = explode(",", $this->attributes['selected_area']);
$query = AreaMaster::find()->where(['IN', 'id', $areaArray])->all();
return $query; //$this->hasMany(AreaMaster::className(), ['IN', 'id', $pks]);
}
VIEW FILE :
<?php
print '<pre>';
print_r($model->areaSelected);
exit;
?>

Related

Joomla - insert multiple rows using single query

At this specific moment, I want to know how to insert two records into DB. Both are almost the same, except only one single column value changes.
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$columns = array('col1','col2', 'col3', 'col4', 'col5');
$values = array(
$db->quote(A),
$db->quote(x1),
$db->quote(x2),
$db->quote(x3),
$db->quote(x4)
);
$values = array(
$db->quote(B),
$db->quote(x1),
$db->quote(x2),
$db->quote(x3),
$db->quote(x4)
);
...
As you can see, only first value changes. Is there some elegant way to do this?
You code seems to be incomplete since it does not assign your values to the query.
Try this instead. It shows how to add the content of $foo to the column myColumn in the table #__mytable.
$query->insert($db->quoteName('#__mytable'))
->columns('myColumn');
->values(implode(',', array(
$db->quote($foo)
)));
$query->execute();
For multiple values this would help:
foreach($myValues as $myValue) {
$query->values(implode(',', array(
$db->quote($myValue),
)));
}
While there is just one value in my example, it is ready to add multiple columns if needed. Just extend the columns() and values() methods.

mySQL query for building dynamically populated model

I have some code below which demonstrates a hard-coded example of what I would like to accomplish dynamically.
At a high level, I wish to do something like select * from view_data_$app_state and then get all of the data from that views table into my mustache templates dynamically.
The code I currently must use to group multiple rows of data for a specific column along with the views data is:
<?php
error_reporting(E_ALL);
class Example {
function __construct(){
try {
$this->db = new PDO('mysql:host=localhost;dbname=Example', 'root','drowssap');
}
catch (PDOException $e) {
print($e->getMessage());
die();
}
}
function __destruct(){
$this->db = null;
}
function string_to_array($links_string){
return explode(",", $links_string);
}
function get_view_data(){
$q = $this->db->prepare('select *, GROUP_CONCAT(`links`) as "links" from `view_data_global` ');
$q->execute();
$result = $q->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
}
$Example = new Example();
$result = $Example->get_view_data();
$result[0]["links"] = $Example->string_to_array($result[0]["links"]);
echo json_encode($result);
This gives me the perfect object while
GROUP_CONCAT seems to be doing the trick this way, however I MUST know the column name that will contain multiple rows before writing the query. I am trying to figure out an approach for this and wish to make a custom query + code example that will transform cols with multiple rows of null null and not empty data into an array like above - but return the data.. again like the code above.
Below is an output of the actual data:
[{"id":"1","title":"This is the title test","links":["main","about","store"]}];
How can I replicate this process dynamically on each view table?
Thank you so much SO!
You can use PDOStatement::fetch to retrieve your results, with fetch_style set to PDO::FETCH_ASSOC (some other values will also provide the same information). In this case, the result set will be array indexed by column name. You can access this information with foreach (array_expression as $key => $value)
See the documentation for additional information.

How to add combined unique fields validator rule in Laravel 4

I am using Laravel 4.2 and mysql db . I have an exam table in which i am taking Exams entry and the fields are --> id | examdate | batch | chapter | totalmarks
I have made a combined unique key using $table->unique( array('examdate','batch','chapter') ); in schema builder.Now I want to add a validation rule to it. I know i can add unique validation by laravel unique validator rule but the problem is ,it checks only for one field . I want it to add uniqueness to the 3 fields combined(user must not be able to add second row with same value combination of examdate,batch and chapter fields).
Is it even possible to do it in laravel 4 .Is there any workaround if its not possible?
You could write a custom validator rule. The rule could look something like this:
'unique_multiple:table,field1,field2,field3,...,fieldN'
The code for that would look something like this:
Validator::extend('unique_multiple', function ($attribute, $value, $parameters)
{
// Get table name from first parameter
$table = array_shift($parameters);
// Build the query
$query = DB::table($table);
// Add the field conditions
foreach ($parameters as $i => $field)
$query->where($field, $value[$i]);
// Validation result will be false if any rows match the combination
return ($query->count() == 0);
});
You can use as many fields as you like for the condition, just make sure the value passed is an array containing the values of the fields in the same order as declared in the validation rule. So your validator code would look something like this:
$validator = Validator::make(
// Validator data goes here
array(
'unique_fields' => array('examdate_value', 'batch_value', 'chapter_value')
),
// Validator rules go here
array(
'unique_fields' => 'unique_multiple:exams,examdate,batch,chapter'
)
);
It didn't work for me so I adjusted the code a tiny bit.
Validator::extend('unique_multiple', function ($attribute, $value, $parameters, $validator)
{
// Get the other fields
$fields = $validator->getData();
// Get table name from first parameter
$table = array_shift($parameters);
// Build the query
$query = DB::table($table);
// Add the field conditions
foreach ($parameters as $i => $field) {
$query->where($field, $fields[$field]);
}
// Validation result will be false if any rows match the combination
return ($query->count() == 0);
});
The validator looks like this. You don't need a particular order of DB table column names as stated in the other answer.
$validator = Validator::make($request->all(), [
'attributeName' => 'unique_multiple:tableName,field[1],field[2],....,field[n]'
],[
'unique_multiple' => 'This combination already exists.'
]);

codeigniter sorting query results returned

I'm looking to sort the results of a query in the controller, "after" it is returned from the model, here is what im trying:
$query = $this->user->get_all_users();
foreach($query as $user){
// dynamically according to my projects' logic
// assigns a grade to each user
$user->grade = assign_a_grade_to_user()
}
what im looking to do is , the results in $query should be sorted according to the grade a student has , and then pass that sorted $query to my view to print
any suggestions or idea to get this ?
NOTE : no issues if we use another temporary variables or data structures like we can store the sorted results in some other variable too
This should do:
function cmp( $a, $b )
{
if( $a->grade== $b->grade){ return 0 ; }
return ($a->grade< $b->grade) ? -1 : 1;
}
$sortedArray=usort($query ,'cmp');
So your code should look like:
$query = $this->user->get_all_users();
foreach($query as $user){
// assigns a grade to each user
$user->grade = assign_a_grade_to_user()
}
$sortedArray=usort($query ,'cmp');
$data['users']=$query;
$this->load->view('home',$data);

Codeigniter - How to get records from database where one fields value is more than another?

In my database I have two columns named 'amount_raised' and 'funding_goal'.
I would like to get all records from my database where the 'amount_raised' is equal to or more than the 'funding_goal'.
I am using Codeigniters active record. This is what I have so far:
function get_recently_successful($limit, $offset){
$data = '';
$this->db->order_by('date','desc');
$this->db->where('published', '1');
$this->db->where('amount_raised >=', 'funding_goal');
$query = $this->db->limit($limit, $offset)->get('projects');
foreach ($query->result() as $row) {
$data[] = array(
'id' => $row->id,
'date' => $row->date,
'project_title' => $row->project_title,
);
}
return $data;
}
The code above just returns all values in the database. Not how I specified it with where. How can I make it work??
Try this instead.
$this->db->where('amount_raised >= funding_goal');
Right now you send the value 'funding_goal' through the query, thus making it:
WHERE amount_raised >= 'funding_goal'
You want it compare with a column and not a string:
WHERE amount_raised >= funding_goal
You can always troubleshoot your query by inserting:
echo $this->db->last_query();
After the $query = row.
If you are using multiple condition in array, you can try the below as well:
$this->db->where(array('status' => 'Active', 'category' => $catId));
You can use another condition as well like this:
$this->db->where('amount_raised >= funding_goal');
You can use the last_query() to see the sql query as well to understand it.