I have three table which are cities, states and country. Each table contains its respective columns as shown below:
cities{id,cityname,states_id}
states{id,statename,country_id}
country{id,name}
Table Relations
cities table contains [states_id]
states table contain [country_id]
If I select particular city, I would need to display [cityname], [statename] and [countryname]
Based on what you provided:
SELECT ci.cityname
, st.statename
, cr.countryname
FROM Cities ci
JOIN States st ON ci.states_id = st.states_id
JOIN Country cr ON st.country_id = cr.country_id
SELECT cities.cityname, states.statename, countryname
FROM cities JOIN
states ON cities.states_id = states.id JOIN
country ON states.country_id = country.id
WHERE cities.id=3;
Assuming 3 is the id of the city you are searching for...
SELECT c.cityname, s.statename, cy.name AS countryname
FROM cities c
INNER JOIN states s ON s.id = c.states_id
INNER JOIN country cy ON cy.id = s.country_id
WHERE c.id = 123
"123" is the city id you want to be informed about.
Related
I would like to receive a data object country. An object country has the following attributes (id, continent_id, language_id).
Table countries {
id, name, continent_id, language_id
}
Table continents {
id, name
}
Table languages {
id, name
}
Instead of getting a DataObject containing only the continent_id and language_id, I want to get the name of the continent and the language. Like that:
{
id: 1,
name: Germany,
continent_id: 1,
language_id: 1,
continent: "europe", // new field
language: "german" // new field
}
How can I achieve this?
you need to join the two additional tables to the man countries
If every country has only one language, this will be enough to INNER JOIN them.
with multiply languages, you need to GROUP BY and use GROUP_CONCAT or the languages
SELECT
countr.id, contr.name, continent_id, language_id
, co.name as continent
, lang.name as language
FROM countries countr
INNER JOIN continents co ON contr.continent_id = co.id
INNER JOIN languages lang ON lang.id = contr.language_id
If a country has multiple languages
SELECT
countr.id, contr.name, continent_id, language_id
, co.name as continent
, GROUP_CONCAT(lang.name) as languages
FROM countries countr
INNER JOIN continents co ON contr.continent_id = co.id
INNER JOIN languages lang ON lang.id = contr.language_id
GROUP BY countr.id, contr.name, continent_id, language_id,co.name
I found a simple solution for my case. Maybe not the smartest but it works. There are probably better solutions. I don't know what influence the size of the data set will have on the performance. I still have to test this.
SELECT c.*, co.name as continent, l.name as language
FROM countries c
JOIN continents co ON co.id = c.continent_id
JOIN languages l ON l.id = c.language_id
WHERE c.id IN (1,2,3);
I have three tables
Student
-------------
id,
matno,
Surname,
faculty_id,
dept_id,
....
Faculty
------------
id,
name,
...
department
-------------------
id,
name,
....
I want to select student details using matno plus the name of faculty and name of department using faculty_id and dept_id . I have tried all SQL JOIN combinations i can think of and I only get one name field.
Also I get null on second query if I try to fetch query using different statement.
Edited
My SQL query is
SELECT * FROM student INNER JOIN faculty ON faculty.id = student.faculty_id LEFT JOIN department ON department.id = student.dept_id WHERE student.matno = 1104
Assuming that faculty_id and dept_id are foreign keys into the Faculty and department tables, this query should give you your desired result (replace ??? with the desired search value of matno):
SELECT s.matno, s.surname, f.name AS faculty, d.name AS department
FROM Student s
JOIN Faculty f ON f.id = s.faculty_id
JOIN department d ON d.id = s.dept_id
WHERE matno = ???
SELECT * FROM
STUDENT S
LEFT JOIN FACULTY F
ON S.FACULTY_ID = F.ID
LEFT JOIN DEPARTMENT D
ON S.DEPT_ID = D.ID WHERE S.MATNO = "$your_matno";
Try using this left join so that at least all students will be in the result set and select the required fields from it.
I have a DB of Students who have a fullname, a location, and a list of schools they frequented.
"student" table
id | fullname | location
------------------------
"location" table
id | zipcode | city
-------------------
"school" table
id | name
---------
"student_school" table (which holds two foreign keys on school and user to create for each user a list of schools)
id | id_student | id_school
---------------------------
I want to perform a search through the students comparing the search term with student.fullname, location.zipcode, location.city, school.name and return all the students matching one (or more) of these conditions.
Note that student can have a null location, so we need an extern join.
Here is example of matching based on regular expressions:
SELECT distinct s.id, s.fullname
FROM student_school ss
JOIN student s ON s.id = ss.id_student
LEFT JOIN LOCATION l ON s.LOCATION = l.id
JOIN school sc ON ss.id_school = sc.id
WHERE (s.fullname RLIKE 'Sasha.*') or
(ifnull(l.zipcode RLIKE '100.*', 0)) or
(ifnull(l.city RLIKE 'New.*', 0)) or
(sc.name RLIKE '.*2')
And here is complete SQL fiddle
So the general idea is to join all student data, filter rows matching at least one criterion and use distinct to group data and avoid duplicating of results.
Update:
To include students with no school records you may use following FROM phrase:
student_school ss
RIGHT JOIN student s ON s.id = ss.id_student
LEFT JOIN LOCATION l ON s.LOCATION = l.id
LEFT JOIN school sc ON ss.id_school = sc.id
I have a hard time figuring out how to write a query that selects all rows that matches certain conditions from one table and extends the rows with data from another table if there is data that matches another set of conditions.
Table: books
id
school
isbn
name
Table: orders
id
school
department
isbn
quantity
The query I have is:
SELECT orders.*, books.name FROM orders
LEFT JOIN books ON orders.isbn = books.isbn
WHERE orders.school = 1 AND orders.department = 2
AND books.school = 1
Now, the problem is that if a school hasn't added their books, isbn and names into the books table I'd still like to have the orders.* data returned with books.name set to null or something similar. Now I get zero rows instead. Is there a way to do this with one query?
Move
and books.school = 1
from the where clause to the from clause.
left join books on orders.isbn = books.isbn
and books.school = 1
Edit starts here
for raheel who says it doesn't matter. Using the world database that came with the MySQL I downloaded, this query
select c.name, city.name cityname
from country c left join city on c.code = city.countrycode
AND city.name = 'toronto'
order by cityname;
returns 239 rows. This query:
select c.name, city.name cityname
from country c left join city on c.code = city.countrycode
WHERE city.name = 'toronto'
order by cityname;
returns 1 row. I think it matters
I have these two tables:
CITY TABLE
CLUB TABLE
What I'm trying to do, is to select with the same query all cities that contain published clubs (published field set to 1) and the total of clubs published in that city.
At the moment, I am doing it with two steps, but I would like to improve performance by merging these in just one query.
SELECT c.id, c.name, c.slug
FROM city c, club cl
WHERE c.id = cl.city_id
AND ( SELECT COUNT(*)
FROM club cl, city c
WHERE cl.city_id = c.id AND cl.published = 1) > 0
GROUP BY c.id
After this, I'm doing a query for each city just to get the COUNT.
Something like this:-
SELECT city.id, city.name, city.slug, COUNT(club.id) AS club_count
FROM city
INNER JOIN club
ON city.id = club.city_id
WHERE club.published = 1
GROUP BY city.id, city.name, city.slug
HAVING club_count > 0