CodeIgniter, Order by number of rows in a separate joined table? - php

I have 4 tables that link together...
Firstly the hotels table
hotel_id
town_id
hotel_name
Then the towns table:
town_id
region_id
town_name
Then the regions table:
region_id
country_id
region_name
Finally the countries table
country_id
country_name
What I need to do is list the towns in order of how many hotels there are within that town.
The reason I have included the regions table and the countries table is because, when displaying that town, I need to display the country it's from. This can only be obtained via the regions table..
Therefore using the active records in CodeIgniter I have done this so far:
$this->db->join('regions','towns.town_region_id = regions.region_id');
$this->db->join('countries','regions.region_country_id = countries.country_id');
$query = $this->db->get('towns');
foreach ($query->result() as $row) {
echo "<li>";
echo "$row->town_name, $row->country_name";
echo "</li>";
}
This outputs:
London, United Kingdom
Washington, United States
New York, United States
Moscow, Russia
etc, etc
Each one of these cities have hotels in them. All I need now is to order them by how many hotels there are in each town..
Any help would be much appreciated! Thanks.

$this->db->select('t.*,c.*,COUNT(h.hotel_id) AS nhotels');
$this->db->from('towns t');
$this->db->join('hotels h','h.town_id = t.town_id');
$this->db->join('regions r','t.town_region_id = r.region_id');
$this->db->join('countries c','r.region_country_id = c.country_id');
$this->db->group_by('t.town_id');
$this->db->order_by("nhotels",'DESC');
$query = $this->db->get();
which will produce the following query:
SELECT `t`.*, `c`.*, COUNT(h.hotel_id) AS nhotels
FROM (`towns` t)
JOIN `hotels` h
ON `h`.`town_id` = `t`.`town_id`
JOIN `regions` r
ON `t`.`town_region_id` = `r`.`region_id`
JOIN `countries` c
ON `r`.`region_country_id` = `c`.`country_id`
GROUP BY `t`.`town_id`
ORDER BY `nhotels` DESC

SELECT
hotels.town_id,
count(hotels.hotel_id) from hotels AS hotels_count,
towns.town_name
FROM
hotels,
LEFT JOIN
towns ON hotels.town_id = towns.town_id
GROUP BY hotels.town_id
ORDER BY hotels_count DESC;

Related

MySQL query to select cities under any region given

I have a database of all regions including cities they are arranged in a tree structure using each ones id as parent region id.
mysql columns are id , parent_region_id , region_name
Structure is like ...
SELECT region_id, region_type, region_name, parent_region_id, parent_region_name FROM regions_data WHERE parent_region_id = 201
Region Types are ....
Country -> Province (State) -> Multi-Region (within a country) -> Multi-City (Vicinity) -> City
Only some countries have Province (State), other countries having Multi-Region (within a country).. and these both may or may not have Multi-City (Vicinity) level under it.
US -> California -> Central California -> San Joaquin Valley -> Mojave & Vicinity -> California City
Like above there will be lot of regions under US and all those regions may have lot of sub regions and cities under those sub regions.
I want a perfect MySQL query which will return all the cities inside the given regions.
Say Give me all cities under US OR Give me all cities under ALASKA STATE
Is there any MySQL experts here to help me ?
You can use several JOINs to get through the sub-levels, and then print only those that have the correct region_type you're looking for. Assuming that you have a maximum of 6 levels (you can add more if needed pretty easily...):
SELECT
IF(`t1`.`region_type`='City', `t1`.`region_name`,
IF(`t2`.`region_type`='City', `t2`.`region_name`,
IF(`t3`.`region_type`='City', `t3`.`region_name`,
IF(`t4`.`region_type`='City', `t4`.`region_name`,
IF(`t5`.`region_type`='City', `t5`.`region_name`, '')
)
)
)
)
FROM `regions_data`
LEFT JOIN `regions_data` `t1` ON (`t1`.`parent_region_id` = `regions_data`.`id`)
LEFT JOIN `regions_data` `t2` ON (`t2`.`parent_region_id` = `t1`.`id`)
LEFT JOIN `regions_data` `t3` ON (`t3`.`parent_region_id` = `t2`.`id`)
LEFT JOIN `regions_data` `t4` ON (`t4`.`parent_region_id` = `t3`.`id`)
LEFT JOIN `regions_data` `t5` ON (`t5`.`parent_region_id` = `t4`.`id`)
WHERE `regions_data`.`region_name` = 'ALASKA STATE'
Try This in mysql:
select #pv:=id as id,region_name, parent_region_id from `your_table_name`
join
(select #pv:=1)tmp
where parent_region_id=#pv
I use 1, you can use your desire id

how to get count of another table

Like below image I have two tables, now I want to get all columns from Restaurant table depending on cat column, and number of records from Foods table that have that Restaurant id.
example : (to get 1,test from Restaurant table and 3 from Foods table).
$sql = "select * from Restaurant,Foods where cat=6..." ;
updated :
$sql = "r.*,(SELECT COUNT(*) FROM restaurant_foods WHERE restaurant_id = r.id)
foods_count FROM restaurant r WHERE r.cats LIKE '%,$cat,%' limit $start,$end"
That should do the job:
SELECT r.*,
(SELECT Count(*)
FROM Foods
WHERE restaurnat_id = r.id) foods_count
FROM Restaurant r
WHERE r.cat = 6

Statement to Count(*) related rows on other table

I have two tables named patient_list and dentist_list where in the dentist can have many patients, I want to get how many patients the dentist has and ordered it.
I have here a sample code where I get each patient of doctor:
$query_dentist = "SELECT * FROM dentist_list ORDER BY ID ASC";
$res_dentist = mysql_query($query_dentist);
if ($res_dentist) {
while ($row_dentist = mysql_fetch_array($res_dentist)) {
}
}
After I get all the dentists, I create a new query inside the while where I will get all the patient count.
$dentist_id = $row_dentist['id'];
$query_patient= "SELECT COUNT(*) as patient_num FROM patient_list
WHERE dentist_id ='$dentist_id'";
$res_patient=mysql_query($query_patient);
if($res_patient)
{
while($row_patient=mysql_fetch_array($res_patient))
{
}
}
For example the output of query is:
doctor 1 has 10 patient
doctor 2 has 5 patient
doctor 3 has 100 patient
Rather than using PHP, is it possible to use a MySQL statement instead? I will create one query only because i need it to sort by number of patient.
You can try using this code:
select d.Name, -- <- put dentist information here
(select count(1) from patient_list p where p.dentist_id = d.dentist_id)
from dentist_list d
order by 2 asc -- <- order by by the 2nd field that is (select count(1...
SELECT COUNT(*) AS Patient_Num FROM patient_list GROUP BY dentist_id ORDER BY 1

MySQL search with joins and match

I've got one table filled with information about companies (tblforetag) in Sweden, one table with provinces (tbllan) and one table with cities (tblstad). The cities are linked to the provinces with id numbers and the company table has a column for the city name (varchar).
How do I search for all the companies in one province?
I have fiddled around with joins but not got it to work. I've got this code right now that works but it will only search for company names and cities (in the company table):
$sql = "
SELECT *,
MATCH(tblforetag.foretag) AGAINST(:keywords) AS kr
FROM tblforetag
WHERE MATCH(tblforetag.foretag) AGAINST(:keywords)
";
$sql .= $locisset ? "AND tblforetag.stad LIKE :location" : "";
$sql .= " LIMIT $offset, $rpp";
$query = $conn->Prepare($sql);
$query->BindValue(':keywords', $keywords);
if($locisset) $query->BindValue(':location', "%$location%");
$query->Execute();
I do not know your table structure but something along these lines shoulod do the trick:
SELECT FROM companies
LEFT JOIN cities ON (companies.city_id = cities.id)
LEFT JOIN regions ON (cities.region_id = regions.id)
WHERE region.name = 'your region'
This would give you the companies in that particular region.
I think it would be better the city_name column in companies table to city_id.
SELECT a.*, p.provincename
FROM companies a, cities c, provinces p
WHERE a.city_name = c.city_name
AND c.city_id = p.city_id
AND p.province_id = 5 // give your province id here

Echo results of a complicated INNER JOIN query with multiple tables

This is my first question here. I have a complicated SQL database and I need to join different tables which have the same column names.
"event" is a sports match. It contains tournament_stageFK which is linked to tournament_stage table, which contains tournamentFK which is linked to tournament table, which contains tournament_templateFK which is linked to tournament_template table, which contains sportFK which is linked to sport table.
So in order to find out what sport the match is from, I need to do an inner join, otherwise I'd have to open the database millions of times. The only way to do it is this, but I don't know how to display the results. My poor attempt to echo the results is below:
$SQL = "SELECT sport.name,
country.name,
tournament_template.name,
tournament.name,
tournament_stage.name,
event.*
FROM tournament_template
INNER JOIN sport
ON tournament_template.sportFK = sport.id
INNER JOIN tournament ON tournament.tournament_templateFK = tournament_template.id
INNER JOIN tournament_stage ON tournament_stage.tournamentFK = tournament.id
INNER JOIN event ON event.tournament_stageFK = tournament_stage.id
INNER JOIN country ON tournament_stage.countryFK = country.id
WHERE DATE(event.startdate) = CURRENT_DATE()
ORDER BY sport.name ASC,
country.name ASC,
tournament_stage.name ASC,
event.startdate ASC";
$result = mysql_query($SQL);
while($get=mysql_fetch_array($result))
{
echo $result['event.name'];
echo "<br>";
}
Your result is fetched as an array indexed by column name, which is "name" for several of your columns... the table name sport, country, template, etc is not part of the returned index. So you need to provide column names that will be unique
Set an alias for each of your columns (e.g. SELECT sport.name AS sport_name) then reference it by its alias within your echo (e.g. $result['sport_name']).
You need to use column aliases and access those in your fetch call. Instead of event.*, be explicit about the columns you need:
$SQL = "SELECT sport.name AS sportname,
country.name AS countryname,
tournament_template.name AS templatename,
tournament.name AS tournamentname,
tournament_stage.name AS stagename,
/* Use explicit column names instead of event.* */
event.name AS eventname,
event.someothercol AS someother
FROM tournament_template
...etc...
...etc...";
// Later...
while($row=mysql_fetch_array($result))
{
echo $row['eventname'];
echo "<br>";
}

Categories