I'm trying to count the number of rows of a DB table that matches some criteria. Now I have the following code:
$q = $this->db->get_where('info', array('city_id'=>$city->id));
$count = $query->num_rows();
In the above code, $count will return the number of rows in 'info' table that can matches city_id of 'info' table with the id of the 'city' table. In 'info' table 'city_id' is a FK.
But here I want to check two conditions, like:
1.Whether it matches the fk(city_id) of info table with the id of 'city' table and
2. Whether it matches another field in the info table(lets say name_id=1);
Is there a way that I can join the two queries with AND?
You can add another condition in second parameter of get_where() function.
$q = $this->db->get_where('info', array('city_id'=>$city->id,'name_id'=>1));
Related
The DB has a table namely records. Among the fields are product_id,quantity,store_id.
I need to get the sum total of quantity of those rows which belong to a certain store_id and then have same product_id values.
For example , the table has values : (2,3,4),(2,1,5),(1 2,2,4) Then I need to get the sum total of quantity along with other columns from 1st and 3rd rows. And the 2nd row will also be present in the result.
Let us assume the Controller name to be RecordController and the model name to be Record.
How should I write the query ?
Edit : the table has values : (2,3,4),(2,1,5),(1 2,2,4)
It can be done using a single query.
Try This:-
DB::table('records')
->select('product_id',DB::raw('sum(quantity) as quantity'),'store_id')
->groupBy('product_id')
->groupBy('store_id')
->get();
Explanation:
This query will fetch all the records & group them by product_id & store_id so will only get a single row for a single product in the store. And then it will display the sum of quantity in the output.
Update:-
Using ORM:-
\App\YourModelName::select('product_id',DB::raw('sum(quantity) as quantity'),'store_id')
->groupBy('product_id')
->groupBy('store_id')
->get();
But you need to write the raw query in any case, it can't be done using default ORM functionality
I want to order by an aggregate function on an associated table's field, but when I debug the SQL query being executed, the associated table, PersonaHistory doesn't even get JOINed, and of course I don't get any results.
Is there a way to achieve this?
Can I force a table to be joined in the query?
$query = $this->Personas->find('all')
->contain(['PersonaHistory'])
->order(['MAX(PersonaHistory.updated)' => 'ASC'])
->group('PersonaHistory.persona_id');
DB: Personas has many PersonaHistory
It looks as if Personas is related to PersonaHistory via hasMany. Only hasOne and belongsTo associations produce a JOIN statement.
A workaround is to rewrite your query as:
$query = $this->PersonaHistory->find('all')
->contain(['Personas'])
->order(['MAX(PersonaHistory.updated)' => 'ASC'])
->group('PersonaHistory.persona_id');
your table name need to be plurialized and you can execute your order and group directly on your associated table field
<?php $query = $this->Personas->find('all')->contain([
'PersonaHistories' => function ($q) {
return $q->order(['Max(updated)' => 'ASC'])
->group('persona_id');
}]);
how to check if value from external table is different than current table then update.
I am updating student firstname from firstname of extstudent. if value is different then only update else dont update
Update student
SET FirstName = FirstName
FROM ExtStudent
You need to join the two tables in your UPDATE (Transact-SQL) statement so that you can compare the two. Both tables have to have the same key so that you can match up the records in your table to your "external" table. In my example below, I'm going to assume that the primary key of both tables is a field called StudentId.
Update Student
SET Student.FirstName = ExtStudent.FirstName
FROM Student
JOIN ExtStudent
ON Student.StudentID = ExtStudent.StudentID
Where Student.FirstName <> ExtStudent.FirstName
This will update the Student table and set the FirstName field to the matching record with the same StudentID in the ExtStudent table where the FirstName fields do not match. Because this is an inner join, it will not update if no matching record is not found.
If you are updating multiple fields and want to update the record if any of the fields changed, then check for inequality for each field in the where clause separated by an OR.
You could technically leave off the where clause because if it doesn't change it would just be updating it to the same value. However keep in mind that this does register as an update, so any update triggers would be fired for all the records... even the ones that didn't change.
Another issue you might run into is if your name fields are nullable. The where clause will return false if either one of the fields are null, so it would not update. You could account for this with the isnull function.
Where isnull(Student.FirstName,'') <> isnull(ExtStudent.FirstName,'')
If changed to a left join with this modification, it would update FirstName to NULL if no match was found.
In CakePHP 3 ORM has changed and I can't find the proper way to select needed data from the database.
In CakePHP 2, I use contain('User.name','User.id'), but In CakePHP 3 this code doesn't work.
So how can I select only id and name from User?
The code:
$query = $data->find()->contain(['Users'])->execute()->fetchAll('assoc');
// I want only user.id and user.name.
$articles = $this->Model->find()
->select(['fields_you_want_from_this_Model'])
->contain(['Assoc_Model' => function($q) {
return $q
->select(['fields_you_want_from_the_associated_model']);
}]);
U must take a look about this page: http://book.cakephp.org/3.0/en/orm/query-builder.html#passing-conditions-to-contain
In certain case you must use autoFields method.
Be carefull with contain when u select few fields in the callable, u always have to select the foreign key also:
When you limit the fields that are fetched from an association, you must ensure that the foreign key columns are selected. Failing to select foreign key fields will cause associated data to not be present in the final result.
I have a query that returns details of an item. It item belongs to a certain category; hence I have linked the ITEMS table to CATEGORIES table with a foreign key being saved to the ITEMS table.
Now, I want the details of any selected item to also display the category name instead of the foreign key. I have tried the INNER JOIN as follows, but surprisingly still the query displays a foreign key.
Here is my query:
/* Create the prepared statement */
if ($stmt = $mysqli->prepare("SELECT categories.category AS category,
items.id,
items.name,
items.description
FROM items
INNER JOIN categories
ON categories.cat_id = items.cat_id
WHERE items.id='$id'")) {
/* Execute the prepared Statement */
$stmt->execute();
/* Bind results to variables */
$stmt->bind_result($id,$category,$name,$description);
/* fetch values */
while ($rows = $stmt->fetch()) {
...
}
...
}
Out put for category name:
<?php
echo $category;
?>
What could be missing here?
Your binding order is wrong, it should be:
$stmt->bind_result($category, $id, $name, $description);
Your order in the SELECT clause matters, so bind_result can figure out wich column binds to wich variable.
This is way out of my element, but nobody answered it yet so I figured I'd take a shot.
Is it because you are selecting 3 items in your query... category, id, description
Then when you are binding variables you're binding 4... $id, $category, $name, $description
So perhaps what is happening is variable $id is actually the category, and $category is actually the id (which is what you're seeing)
You seem to be fetching 3 items (from your select) to 4 variables, I don't think this is good.