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'm working on a codeigniter project.
Here are my tables
category
cid cname
5 general
6 science
7 math
books
bid bname
12 first
13 second
14 third
15 fourth
16 fifth
17 sixth
dir
id bid cid
1 12 5
2 13 6
3 14 7
4 15 6
5 16 5
6 17 5
As you can see joining the tables is easy but here is what I need to do.
Create a function that will give me category name(cname) and the number of books in that category. For example the outcome should be like
general 3
science 2
math 1
here is my WIP model
function category_details(){
$this->db->order_by('cname','asc');
$query=$this->db->query('Select * from dir join category on category.cid=dir.cid join books on dir.bid=books.bid');
return $query->result_array();
}
Any help would be much appreciated.
The query should be like this to get expected result
Select category.cname,count(dir.cid) from dir join category on category.cid=dir.cid join books on dir.bid=books.bid group by category.cname
And your function should be like this
function category_details(){
$this->db->order_by('cname','asc');
$query=$this->db->query('Select category.cname,count(dir.cid) from dir join category on category.cid=dir.cid join books on dir.bid=books.bid group by category.cname');
return $query->result_array();
}
you can refer this code COUNT / GROUP BY with active record? for proper CI query.
I have been tasked with creating a search function that when searched, certain fields will have more weight than others.
Here is an simplified example.
cars (table)
year, make, model, color, type (columns)
Let's say someone searches for the following:
Year: 1968
Make: Ford
Model: Mustang
Color: Red
Type: Sports Car
If the cars in the table have none of the correct fields they should not show up, but if record has some of the correct fields but not all they should still show up. But certain fields should be weighted higher than others.
For instance maybe they are weighted like this:
Column - Weight
Year - 30
Make - 100
Model - 85
Color - 10
Type - 50
So if a record matches the search in the "make" field and the "model" field, that record would be above a record that matched in the "year", "color" and "type" field, because of the weights we placed on each column.
So lets say that the query matches at least one field for two records in the database, they should be ordered by the most relevant based on the weight:
1971, Ford, Fairlane, Blue, Sports Car (weight = 185)
1968, Dodge, Charger, Red, Sports Car (weight = 90)
I have been racking my brain trying to figure out how to make this work. If anyone has done something like this please give me an idea of how to make it work.
I would like to do as much of the work in MySQL as possible via joins, I think this will be bring up the results faster than doing most of the work in PHP. But any solution to this problem would be much appreciated.
Thanks in advance
Bear with me, this is going to be a strange query, but it seems to work on my end.
SELECT SUM(
IF(year = "1968", 30, 0) +
IF(make = "Ford", 100, 0) +
IF(model = "Mustang", 85, 0) +
IF(color = "Red", 10, 0) +
IF(type = "Sports Car", 50, 0)
) AS `weight`, cars.* FROM cars
WHERE year = "1968"
OR make = "Ford"
OR model = "Mustang"
OR color = "Red"
OR type = "Sports Car"
GROUP BY cars.id
ORDER BY `weight` DESC;
Basically, this groups all results by their id (which is necessary for the SUM() function, does some calculations on the different fields and returns the weight as a total value, which is then sorted highest-lowest. Also, this will only return results where one of the columns matches a supplied value.
Since I don't have an exact copy of your database, run some tests with this on your end and let me know if there's anything that needs to be adjusted.
Expected Results:
+============================================================+
| weight | year | make | model | color | type |
|============================================================|
| 130 | 1968 | Ford | Fairlane | Blue | Roadster |
| 100 | 2014 | Ford | Taurus | Silver | Sedan |
| 60 | 2015 | Chevrolet | Corvette | Red | Sports Car |
+============================================================+
So, as you can see, the results would list the closest matches, which in this case are two Ford (+100) vehicles, one from 1968 (+30), and a Red Sports Car (10 + 50) as the closest matches (using your criteria)
One more thing, if you also want to display the rest of the results (ie results with a 0 weight match score) simply remove the WHERE ... OR ..., so it will check against all records. Cheers!
Further to the comments below, checking the weight after a LEFT JOIN on a pivot table:
SELECT SUM(
IF(cars.year = "1968", 30, 0) +
IF(cars.make = "Ford", 100, 0) +
IF(cars.model = "Mustang", 85, 0) +
IF(cars.color = "Red", 10, 0) +
IF(types.name = "Sports Car", 50, 0)
) AS `weight`, cars.*, types.* FROM cars
LEFT JOIN cars_types ON cars_types.car_id = cars.id
LEFT JOIN types ON cars_types.type_id = types.id
WHERE year = "1968"
OR cars.make = "Ford"
OR cars.model = "Mustang"
OR cars.color = "Red"
OR types.name = "Sports Car"
GROUP BY cars.id
ORDER BY `weight` DESC;
Here is a picture of the LEFT JOIN in practice:
As you can see, the Cobalt matches on color (silver) and model (Cobalt) (85 + 10) while the Caliber matches on type (Sports Car) (50). And yes, I know a Dodge Caliber isn't a Sports Car, this was for example's sake. Hope that helped!
If I understand your logic you can just do something like direct comparison in PHP between the value requested and the value returned.
The query will sound like:
SELECT Year,Make,Model,Color,Type
FROM table
WHERE year='$postedyear' OR make='$postedmake'
OR model='$postedmodel' OR color='$postedcolor'
Then in php looping between the results:
foreach($results as $result){
$score = 0;
if($result['year']==$postedyear{$score=$score+30;}
//continue with the other with the same logic.
}
After each foreach iteration $score will be the score of that selected row. If you push the score to the $result array you can also sort it by score before displaying the results.
Variation on #lelio-faieta
In php you can have a result array containing arrays of values for each item matching at least one of the search terms, the associative array of values to match and the associate array of weights, both with the same indexes. You would just get an array of matches for each index. (maybe use array_intersect_assoc()) Then you multiply by the weights and sum, add to the original data. Then you do have to sort the result array at that point.
There is a solution doing this via the mysql query directly, but that would end up with an overgrown resource thirsty query for every single search you perform.
Doing it in PHP is not much difference in resource usage, bounding to several loops in results and processing it.
I've had a very similar project and my best suggestion would be: "use SphinxSearch"
Very easy to install, needs a bit of a learning curve to setup afterwards, but very similar to mysql queries etc. With this you can apply weights to every column match and rank your results afterwards.
Also, it is a multitude of time faster that typical mysql queries.
Hello friends I have 2 Mysql tables with 1:N relationship between category and category_Dates
Category:
ID Category Frequency
1 Cat A Half-yearly
2 Cat B Quarterly
category_Dates:
ID CatID Date
1 1 01-Jan-15
2 1 01-Jul-15
3 2 01-Jan-15
4 2 01-Apr-15
5 2 01-Jul-15
6 2 01-Oct-15
based on the category frequency I am entering number of records automatically in category_date. Eg
When category frequency = quarterly, I am entering 4 records in category_date with ID of that category. And dates will be entered later.
I am little confused if in case on wants to edit the frequency from halfyearly to yearly. How to change number of records. Please help with your valuable suggestions. I am using laravel 4 framework with mysql
best way would be with 3rd table joining Dates and Categories. See little carefully ,you can see its actually Many to Many relationship (N to N) as 1 category can have multiple dates. and one date may be part of multiple categories, like say 01-Jan-15 is part of Category 1 and 2 as well.
So use
category table
id Category Frequency
1 Cat A Half-yearly
2 Cat B Quarterly
date table
id Date
1 01-Jan-15
2 01-Apr-15
3 01-Jul-15
4 01-Oct-15
categories_dates table
ID CatID Date_id
1 1 1
2 1 3
3 2 1
4 2 2
5 2 3
6 2 4
If you change the frequency in Category table, retrieve the update category_id,
delete all from category_dates where CatId=category_id then insert the new entries in category_Dates.
Hope this help.
I assume your models are Category and CategoryDates.
let's update category id 1 from Half-yearlyto to Quarterly
$query = Category::find(1);
$query -> Frequency = 'Quarterly';
$query -> save();
return $query -> id;
in the CategoryDates model you would delete the catID = 1 and insert new data
$catID = 1;
$query = CategoryModel::where('CatId',$catId) -> delete();
$data = ['CatId' => $catID,'date' => 01-Jan-15, ....];
CategoryModel::create($data);
of course assuming that you would return the newly updated category id to your controller and call a funtionn to do the update in your CategoryModel.
Hope this help.
I have a products index on sphinx . Im searching and filtering by category. Im sorting via "id desc" and with that settings i see the last products. Thats okey. But the real problem is that :
I want to show that not listed one category and the other (because my products added one, and than the other). i want to list both id desc (the last products first) and shuffled category.
Via design:
id category_id name
-- ----------- ----
1 1 a
2 1 b
3 1 c
4 2 d
5 2 e
6 2 f
Now (The order):
f-e-d-c-b-a
But i want
f-c-e-b-d-a
My sphinx code :
$sphinx = new SphinxClient();
$sphinx->SetServer("127.0.0.1", 9312);
$sphinx->SetMatchMode(SPH_MATCH_EXTENDED2);
$sphinx->SetRankingMode(SPH_RANK_WORDCOUNT);
$sphinx->SetSortMode(SPH_SORT_EXTENDED, 'id DESC');
$sphinx->SetArrayResult(true);
$filtersArr = $this->getSphinxFilterParams($params);
foreach ($filtersArr['filter'] as $attr => $val)
{
$sphinx->SetFilter($attr, $val[0], $val[1]);
}
Is there anyway to make that ?
There is a thread on the sphinx forum about this here:
http://sphinxsearch.com/forum/view.html?id=10546
While it is mostly possibly with the sphinxAPI (via the undocumented setOuterSelect), suggest migrating to SphinxQL, as it will be most easier to work with.