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
Related
I'm building a website for Airplane Tickets, i have 2 tables, AIRPORTS and AIRPLANES, the AIRPLANES table has 2 columns containing its airport destination id(ID_DESTINATION) and its airport origin id(ID_ORIGIN), what i want to do is to loop all of the AIRPLANES using while with the AIRPORT_NAME as its origin and destination from the AIRPORTS table, how can i do that?
this is the query i'm using :
SELECT a.ID_PLANE, a.PLANE_NAME,
a.ID_ORIGIN, a.ID_DESTINATION,
a.TAKEOFF, a.LANDING, a.PRICE,
b.ID_AIRPORT, b.AIRPORT_NAME
FROM AIRPLANES AS a
LEFT JOIN AIRPORTS AS b
ON a.ID_ORIGIN = b.ID_AIRPORT
Thanks in advance.
Notice I aliased O for origin D for destination
Assuming you just want the names of airports for each airplane (flight)
SELECT a.ID_PLANE
, a.PLANE_NAME
, a.ID_ORIGIN
, a.ID_DESTINATION
, a.TAKEOFF
, a.LANDING
, a.PRICE
, o.ID_AIRPORT as Orig_ID
, o.AIRPORT_NAME Orig_Name
, d.ID_AIRPORT as Dest_ID
, d.AIRPORT_NAME Dest_Name
FROM AIRPLANES AS a
LEFT JOIN AIRPORTS AS o
ON a.ID_ORIGIN = b.ID_AIRPORT
LEFT JOIN AIRPORTS d
ON a.ID_DESTINATION = b.ID_AIRPORT
Why dont you just use a sql-join?
http://www.sql-join.com/
I have these tables:
CATEGORIES:
id
name
KIBE_TRAEGER:
id
name
COUNTIES:
id
region_id
country_id
county_code
county_de
REGIONS:
id
country
region_de
CONTACTS:
id
firstname
surname
company
zipcode
city
region --> =regions.id --> should show regions.region_de
county --> =counties.id --> should show counties.county_de
tel1
tel2
mobile
fax
email1
email2
homepage
categories --> =categories.id BUT in table "contacts" it's written
with ;catnr; (e.g. an entry can have more than 1 entry:
";6;;7;;8;;16;") --> should show categories.name
notes
active
pernr
KIBE_CONTACTS:
id
openinghours
costs
groups
handicapplaces
freeplaces
traeger --> =kibe_traeger.id same as categories ;traegerId; (e.g.";1;;5;") --> should show kibe_traeger.name
and I want to combine all of them to export it to csv.
Btw. i tried my poor queries so far directly in phpmyadmin with left join and inner join but I'm relly poor in SQL stuff and wont learn it anymore :P ...
My code so far (edited according to Matt Cremeen's answers):
Working:
SELECT
contacts.id, contacts.firstname, contacts.surname, contacts.company,
contacts.zipcode, contacts.city, contacts.country, contacts.region,
contacts.county, contacts.tel1, contacts.tel2, contacts.mobile,
contacts.fax, contacts.email1, contacts.email2, contacts.homepage,
contacts.active, contacts.pernr, kibe_contacts.id as contacts_id,
kibe_contacts.openinghours, kibe_contacts.costs, kibe_contacts.groups,
kibe_contacts.handicapplaces, kibe_contacts.freeplaces,
kibe_contacts.traeger, kibe_traeger.id as traeger_id, kibe_traeger.name,
counties.id as counties_id, counties.region_id as region_id,
counties.country_id as country_id, counties.county_code, counties.county_de,
regions.id as regions_id, regions.country as regions_country, regions.region_de
FROM
contacts
INNER JOIN
kibe_contacts ON contacts.id = kibe_contacts.contact_id
INNER JOIN
regions ON contacts.region = regions.id
INNER JOIN
counties ON contacts.county = counties.id
Not working:
INNER JOIN
kibe_traeger ON kibe_contacts.traeger = kibe_traeger.id
INNER JOIN
categories ON contacts.categories = categories.id;
I'm getting a "Null-Result" I think I know why I get this error: because in the column kibe_contacts.traeger and contacts.categories there are more than one values which are separated with ; e.g. an entry can have more than 1 entry: ;6;;7;;8;;16; but in categories.id there is always just a single id e.g. 4.
Is there any solution to query this out?
Last Edit: Solved the second problem by myself: i exported the list and did it with search & replace.
Thanks again to all the helpers!
Assuming that the id field corresponds to each table, you are going to want to join each table on that field. I won't write all of the code here, but it'll start like this
SELECT contacts.id, contacts.firstname, contacts.surname, ...
FROM contacts
INNER JOIN
kibe_contacts
ON contacts.id = kibe_contacts.id
INNER JOIN
regions
on contacts.region_id = regions.id
...
try to use GROUP_CONCAT function of MySQL. Here my sample SQL
I've 2 tables, clientes ('Id' int, 'nome' varchar(50) )
clientes
1 Rafael
2 Jony
3 Smith
and clientes_devices ('Id' int, 'id_cliente' int, 'device' varchar(50) )
clientes_devices
1 1 AsusZenFone
2 1 MotorolaG
3 2 WindowsPhone
Here is the select command
select c.nome, GROUP_CONCAT(DISTINCT d.device SEPARATOR ',') AS Device
from clientes c
join clientes_dispositivos d on (c.id = d.id_cliente)
where c.id = 1
this is the output
Without the function, I got this
I have a 3 MySQL tables which I need to get results from and which are:
1. Towns
Fields Towncode and Townname
2. Students
Fields student_id,name,surname,address,streetcode,towncode,HeadOfFamily
3. Phonebank
Fields student_id,contacted,towncode
Now I need a mysql statement (a) to get the total number of households from the students table and also (b) the number of students contacted for that particular town.
up to step (a) I managed which and is extremely fast which is:
SELECT
t.towncode as towncode,
t.townname as townname,
(SELECT COUNT(*)
FROM students p
WHERE p.towncode=t.towncode
and p.student_hh='H') AS households
FROM
towns t
ORDER BY
t.towncode ASC
but I cannot manage to insert as well another SELECT STATEMENT to get the number of calls fr that particular town.
Can you kindly assist please?
Doing a per-record count on towns is probably hurting you. I would pre-query the students table first, THEN use that joined to the towns.
For indexes, I would have the following indexes
table index
towns ( towncode, townname )
students ( student_hh, towncode )
SELECT
t.towncode as towncode,
t.townname as townname,
TownCnts.households
FROM
towns t
JOIN ( SELECT
p.towncode,
COUNT(*) households
from
students p
where
p.student_hh = 'H'
group by
p.towncode ) as TownCnts
ON t.towncode = TownCnts.towncode
ORDER BY
t.towncode ASC
Assuming that the number of "calls" is the number of rows in the PhoneBank table with a particular town code, then you can add another subselect:
SELECT t.towncode as towncode, t.townname as townname,
(SELECT COUNT(*)
FROM students p
WHERE p.towncode = t.towncode and p.student_hh='H'
) AS households,
(SELECT COUNT(*)
FROM phonebank pb
WHERE pb.towncode = t.towncode
) AS calls
FROM towns t
ORDER BY t.towncode ASC ;
Your question is a little vague. It is possible that you want count(distinct studentid) in the second query, rather than count(*).
To optimize this query, create the following indexes:
towns(towncode)
students(towncode, student_hh)
phonebank(towncode)
I currently have this code.
switch($search_topic)
{
case 'Title':
$stmt = $dbh->prepare("SELECT game_id, title, platform_name, author_name, price
FROM games
WHERE title
LIKE :search_term");
break;
case 'Platform':
$stmt = $dbh->prepare("SELECT game_id, title, platform_name, author_name, price
FROM games
INNER JOIN platforms ON games.platform_id = author.platform_id
WHERE platform_name LIKE :search_term");
break;
}
the search_topic variable is coming from a listbox on the previous webpage, the Title search works correctly as its simply just search one MySQL table. The Platform search is being abit difficult as I'm attempting to search multiple tables, If that makes sense.
The games table has a column called "platform_id" this this links to the platform table where the key field links to what platform it is under. So how would I go about getting the "platform_id" from the games table and then link it to the "platforms" so I retieve the "platform_title" and then use that to search against.
Schema: http://sqlfiddle.com/#!2/3d3e3/6
Based off of your fiddle, here's the update for you:
SELECT g.game_id, g.title, p.platform_name, a.author_name, g.price
FROM games g
INNER JOIN platforms p ON p.platform_id = g.platform_id
INNER JOIN author a ON a.author_id = g.author_id
WHERE g.title LIKE 'Skyrim';
You would obviously change WHERE g.title LIKE 'Skyrim'; to whichever field you would like to filter on. So the platform query would be:
SELECT g.game_id, g.title, p.platform_name, a.author_name, g.price
FROM games g
INNER JOIN platforms p ON p.platform_id = g.platform_id
INNER JOIN author a ON a.author_id = g.author_id
WHERE p.platform_name LIKE 'Xbox';
I would also suggest that you change your CHARSET to utf8 instead of latin1, assuming this reflects your production database setup.
SELECT games.game_id,
games.title,
games.platform_name,
games.author_name,
games.price,
games.platform_id,
platforms.platform_id,
platforms.platform_name
FROM games, platforms
WHERE
games.platform_id = platforms.platform_id
AND
platform.platform_name LIKE %:search_term%
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;