I am having trouble with variables being returned having NULL values randomly.
I have this model association structure:
Truck $hasOne Chassis
Chassis $hasMany Make
Chassis $hasMany Model
Truck $hasOne Type
Randomly results will have null results for type or null results for make and model, but other results will have the correct results..
0 (array)
Truck (array)
Chassis (array)
id 1
make_id 2
model_id 2
title Basic Chassis
description This Basic Chassis is good for a lot of things, but advanced stuff is not one..
Truck_make (empty)
Truck_model (empty)
1 (array)
Truck (array)
Chassis (array)
id (null)
make_id (null)
model_id (null)
title (null)
description (null)
Above you can see that 2 trucks are loaded, the first one's chassis loaded and the make and model id's, but not the array's for the make and model. Also the second vehicle had nothing load..
Here's a screenshot of associations from MySQL Workbench:
http://d.pr/i/JgMt
These are the queries that are called.
Query Affected Num. rows Took (ms) Actions
SELECT `Truck`.`id`, `Truck`.`chassis`, `Truck`.`type`, `Truck`.`title`, `Truck`.`ref`, `Truck`.`hide_truck`, `Truck`.`featured_gallery`, `Truck`.`featured_home`, `Truck`.`created`, `Chassis`.`id`, `Chassis`.`make_id`, `Chassis`.`model_id`, `Chassis`.`title`, `Chassis`.`description`, `Type`.`id`, `Type`.`title`, `Type`.`desc` FROM `douglass_cake`.`trucks` AS `Truck` LEFT JOIN `douglass_cake`.`chassis` AS `Chassis` ON (`Chassis`.`id` = `Truck`.`id`) LEFT JOIN `douglass_cake`.`types` AS `Type` ON (`Type`.`id` = `Truck`.`id`) WHERE 1 = 1
SELECT `Truck_make`.`id`, `Truck_make`.`make`, `Truck_make`.`hide_make` FROM `douglass_cake`.`truck_makes` AS `Truck_make` WHERE `Truck_make`.`id` = (1)0
SELECT `Truck_model`.`id`, `Truck_model`.`model`, `Truck_model`.`hide_model` FROM `douglass_cake`.`truck_models` AS `Truck_model` WHERE `Truck_model`.`id` = (1)
I figured out this issue. Looks like MySQL Workbench wrote the tables with an offset of 2 instead of 1. Cakephp was expecting the default offset so when the rows were returned to cakephp it read it starting at 1 while MySQL was told to start at 2. FIxes. Stupid error
Related
I am trying to sort alphabetically. I am calling data from database. In the table i am storing ID's of Make like Suzuki, Toyota. I have 1 table naming Make in which i am saving Makes like Toyota.
then i am adding into Models with respect to Make like Land Cruiser is a model and its Make is Toyota. i am inserting ID of the Make from Make's table. then on front end, i am converting the ID's back to Make's name. I want to show Makes name alphabetically.
Here what i do
<?php
$SelectMainCats = mysqli_query($con, "SELECT * FROM model");
$S_NO = 0;
while($row=mysqli_fetch_assoc($SelectMainCats)){
$S_NO++;
$getid = $row['id'];
//converting ids to names
$main_make_query = mysqli_query($con,"SELECT * FROM make WHERE id=".$row['make']);
$main_make = mysqli_fetch_assoc($main_make_query);
?>
Front end calling
<td><?php echo $main_make['maker_name'];?></td>
Running a query and looping through the result set to run more queries is almost always the wrong way to SELECT data. You should be using a JOIN to link the two tables, then one query will retrieve all the data, sorted in the order you want.
Based on this data:
Makes
id makerName
1 Ford
2 Suzuki
3 Toyota
Models
id makerId modelName
1 1 Prefect
2 2 Swift
3 3 LandCruiser
4 3 Celica
5 1 Orion
6 2 Splash
7 1 Mondeo
This Query
SELECT b.makerName, a.modelName FROM models a join makes b on a.makerId = b.id order by makerName;
Gives this result
makerName modelName
Ford Prefect
Ford Orion
Ford Mondeo
Suzuki Swift
Suzuki Splash
Toyota LandCruiser
Toyota Celica
I have models/tables as follows:
table room_category
id room_category
1 Classic
2 Deluxe
table room_charges
id room_category room_name room_charges
1 1 c1 600
2 2 d1 800
table ipd_charges
id doctor room_category charges_cash charges_cashless
1 1 1 200 300
2 1 2 300 400
table patient_detail(patient_admission)
id patient_name tpa_name(if not null, equivalent to charges_cashless)
1 1 Null
2 2 1
table daily_ward_entry
id patient_name room_name(id) doctor_name(id) charges ( from ipd_charges)
1 1 1 1 200
2 2 2 1 400
Now there is a dropdown field in daily_ward_entry table for doctor. When I select the drop-down field the charges field needs to be autofilled.
I achieve this using Jason and ajax with the following code without taking into account the room_category. but the charges vary for room_category.(this is only working after saving the record, I prefer if there is someway to pull the charges before save.)
Here is my code in the controller:
public function actionChargesCash($id){
$model = \app\models\IpdCharges::findOne(['doctor'=>$id]);
return \yii\helpers\Json::encode(['visit_charges'=>$model->charges_cash]);
}
public function actionChargesCashLess($id){
$model= \app\models\IpdCharges::findOne(['doctor'=>$id]);
return \yii\helpers\Json::encode(['visit_charges'=>$model->charges_cashless]);
}
I have also tried this variaton:
public function actionChargesCash($id){
$model = \app\models\IpdCharges::find()
->where(['doctor'=>$id])
->andwhere(['room_category'=>'daily_ward_entry.room_name'])->one();
If I replace the 'daily_ward_entry.room_name' with room_name id like 3 or 6, I am getting the result, which means I am not using the correct syntax for referring the column from current table.
How can I include the condition for room_name in the above code?
Thanks in advance for your valuable help.
daily_ward_entry.room_name is meaningless without any relation or join or sub-query. Actually, the query does not know the daily_ward_entry.
Suggestions:
1- Create a relation and use with or Join With
2- Create a query with Join of daily_ward_entry and ipd_charges on room_name=room_category
3- Create a query with a sub-query, to find all|one IpdCharge(s) that have room_category in SELECT room_name FROM daily_ward_entry
All of above suggestions satisfy your requirements.
Another important note:
andWhere()/orWhere() are to apply where to the default condition.
where() is to ignore the default condition
I don't see any default condition (Overridden Find()), So, there is no need to use andWhere, Just:
where(['doctor'=>$id,'room_category'=>3,...])
Would be sufficient.
I have a table categories which contains the columns ID & ParentID I would like to add a field called Level, which states which level in the category tree each category is.
I think i found my solution but it is in sql not mysql. So i have been converting it to the correct syntax. However, i think im missing a step. So, here is my code:
ALTER TABLE categories DROP Level;
ALTER TABLE categories ADD Level INT NULL;
UPDATE categories
SET Level = 0
WHERE ParentID IS NULL;
UPDATE categories AS A
INNER JOIN categories B ON A.ParentID = B.ID
SET A.Level = B.Level + 1
WHERE A.Level IS NULL AND
B.Level IS NOT NULL;
I think the problem may lie in the fact that in my DB The order of the categories do not come in any specific order, what i mean is as follows:
ID ParentID
2 NULL 0
4 55
7 2
.....more categories
55 2
So what i would like it do do is:
ID Parent Level
2 NULL 0
3 55 2
7 2 1
....
55 2 1
However, i think, but i might be wrong, is that i need to either order by ParentID first before i do the last operation, or my query is missformed.
I am not getting any errors however, but just not getting the results i am expecting this is what im getting;
ID Parent Level
2 NULL 0
3 55 NULL
7 2 1
....
55 2 1
Any ideas?
The question is how many levels do u have?
If they are 3 levels than u can do it like this
ALTER TABLE categories DROP Level;
ALTER TABLE categories ADD Level INT NULL;
UPDATE categories SET Level = 0 WHERE ParentID IS NULL;
UPDATE categories SET level = 1 where parentID = 2;
UPDATE categories SET level = 2 where parentID > 2;
I have a parent category that holds all Cars names, denoted by parent_name in table "parent". For each of these parents, there could be any number of car models & they all go in table called "model". Each of these models can have any number of images & refereced via the model_id as the Foreign Key. My task is to show all the Parent Name only once (as in a group) and at the same time, list all the models under that Parent with just 1 corresponding image. The parent_name should not be shown more than once.
MY EXPERIMENTS:
I basically tried to write 2 queries. One was to left join "parent" table on "models" & use GROUP BY parent_id and then in the while loop, write another query to fetch only 1 image using by joining the models & images tables by using model_id field. But doing this lists only 1 Model, even though there are multiple models. So I tried to use GROUP BY parent_id, model_id. Using this does show all the models but at the same time, also repeats showing the parent_name & I need the parent_name to show only once throughout the page. You can say that I am trying to GROUP the model_name under the parent & show all the models under a single parent and I am showing only 1 image of the model. If somehow I can avoid showing the parent_name multiple times, the issue would be solved.
Following are my table schemas:
//Table parent
parent_id parent_name
1 Par1
2 Par2
//Table model
model_id parent_id model_name
1 1 Model1
2 2 Model2
3 1 Model3
4 1 Model4
5 2 Model5
//Table model_images
image_id model_id
1 1
2 1
3 1
4 2
5 3
6 3
DESIRED OUTPUT:
Par1 ---> This is the parent. Needs to be shown only once.
Model1 --> This is a model. List all models that belong to this parent.
image_id 1 -> Show only 1 image of the model (model may have multiple images but I need just one)
Model3 --> This is a model.
image_id 5 -> Show only 1 image of the model
Model4 --> This is a model.
No Image -> Note that no image exists for this model. So we show "No Image" text.
------------------------------------------------------------
Par2 ---> This is the parent. Needs to be shown only once.
Model2 --> This is a model.
image_id 4 -> Show only 1 image of the model
Model5 --> This is a model.
No Image -> Note that no image exists for this model. So we show "No Image" text.
I need the PHP & mySQL code to achieve the above. All help in resolving the issue is appreciated.
Thank you very much.
EDIT 1:
Sorry, I forgot to add this. I am non-object oriented programmer. So I would really be thankful if you can avoid object oriented code in your solution and show me the same in a non-oops way. Thanks.
You might do it in one query and than combine it to an associative array:
$query = ' SELECT *
FROM parent AS p
LEFT JOIN model AS m
ON p.id = m.parent_id
LEFT JOIN model_images AS m_i
ON m.model_id = m_i.model_id';
$array = array();
if($mysli->query($quer)){
while($row = $result->fetch_assoc()){
$array[$row['parent_name']][$row['model_id']] = $row;
}
}
You will than have an associative array with the parent name as the key of the array. You can then use a for loop to print the key only once (with $i = 0) but the rest value by value.
Is that clear enough?
EDIT: Your array than might look like this:
Array(
'Par 1' =>
Array(
[0] => Array(
'parent_id' => 1,
'parent_name' => 'Par 1',
'model_id' => 1,
'model_name' => 'Model 1',
'image_id',
),
[1] => Array(...)
),
'Par 2' => Array(...)
)
So to print out you need two loops. One for the parents (and there names) and one for their childs (models in this case).
foreach($array as $par_name => $models){
echo 'Parent name: '.$par_name.'<br />';
echo 'Model ID: '.$models[0]['model_id'].', Model Name: '.$models[0]['name']; // replace with your desired output
}
Now an idea of how it works? An sure as Artefacto said, you can use procedural functions if you don't like OOP functions.
The category table looks like somewhat as below:
id -- name -- parent_id
1 -- Men -- 0
2 -- Women -- 0
3 -- Shirts -- 1
4 -- Half-sleeve -- 3
5 -- Full-sleeve -- 3
Relationship table:
Product_id -- Category Id
1 -- 2
2 -- 2
3 -- 4 ....
I can retrieve the number of products in any one category and its immediate sub categories with ease with ease. But if there are more than 2 levels things get messy.
So my question is How do I get the number of all of the products in Men and its sub categories. Or Shirts and its subcategories?
Any ideas, Thanks.
UPDATE:
I know there is Nested Set Model but I am not in position to change the structure to that now.
If it is possible I would check out Managing Hierarchical Data in MySQL.
It is hard to get your head around at first, but it makes tasks like this much easier.
If you can't do this, you will have to do a recursive function, e.g.:
$prods = 0;
function getProdsInCat($cat)
{
global $prods;
$prods += mysql_result(mysql_query(SELECT COUNT(`Product_id`) FROM `prod_to_cat` WHERE `Category Id` = '".$cat."'),0);
$moreCats = mysql_query("SELECT `cat_id` FROM `cats` WHERE `parent_id` = '".$cat."'");
while($cats = mysql_fetch_assoc($moreCats)
{
getProdsInCat($cats['cat_id']);
}
}
Assuming you can add an extra column to the categories table.
Said column will have the path to the category.
id -- name -- parent_id path
1 -- Men -- 0 0/
2 -- Women -- 0 0/
3 -- Shirts -- 1 0/1
4 -- Half-sleeve -- 3 0/1/3
5 -- Full-sleeve -- 3 0/1/3
That way finding all the subcategories becomes one query:
SELECT id as CatId FROM categories WHERE path LIKE '0/1/%';
And to get the count of all the products within a category and its childrens is pretty easy too:
SELECT count(p.id) as Total
FROM products as p
JOIN categories as c ON p.category_id = c.id
WHERE c.path like '0/1/%';
Pretty efficient query.
This article provides more information: More Trees & Hierarchies in SQL