INNER JOIN mysql return nothing - mysql

I'm trying to get the city name for my drop down list but using INNER JOIN and mysql but I end up getting no result, Please help me identify the issue. Thanks so much in advance.
SELECT city_name
from cities
INNER JOIN states
ON cities.city_id = states.state_id
GROUP BY cities.city_name
and here is my cities table database
and here is my states table databse

Your query should be:
SELECT city_name
from cities
INNER JOIN states
ON cities.state_id = states.state_id
GROUP BY cities.city_name
You are matching city_id with State_Id which wouldn't fetch you anything

Related

Problems with subqueries using Sakila

Using the Sakila DB, i am trying to get the Country name, the number of cities that a country have, and the number of addresses of a country
Using the next query i get the country and the cities number
SELECT CO.country,COUNT(CI.city_id)
FROM city CI
INNER JOIN country CO ON CO.country_id = CI.country_id
GROUP BY CO.country;
Using this other one i get the addresses number
SELECT CO.country,COUNT(A.address_id)
FROM city CI
INNER JOIN address A ON A.city_id=CI.city_id
INNER JOIN country CO ON CI.country_id=CO.country_id
GROUP BY CO.country;
I was hinted to use Subqueries to get the desired results, but i can't find how to get all that in one table. Any suggestions?
This is actually a tricky problem. Your join approach can be made to work, with some slight modifications. The total count across each country group will give the number of addresses in that country. But to get the city count for a country, we can count the distinct city names in each country group. The need for DISTINCT here is that the join to the address table will cause each city name to replicated however many times an address appears in a given city. Taking the distinct city count gets around this problem.
SELECT
co.country_id,
COUNT(DISTINCT ci.city_id) AS city_cnt,
COUNT(a.city_id) AS address_cnt
FROM country co
INNER JOIN city ci
ON co.country_id = ci.country_id
INNER JOIN address a
ON ci.city_id = a.city_id
GROUP BY
co.country_id;
You can achieve the result using below sub query. This is basically to show how you can write it. Its recommended to use join(Refer answer from Tim Biegeleisen) than Sub queries as it gives good performance.
select
Co.Country,
(Select COUNT(1) from City Ci where Ci.countryid=co.countryid) CityCount,
(Select COUNT(1) from Address A Join city c on a.city_id=c.city_id where C.countryid=co.countryid) AddressCount
From Country Co

How to bring ALL data from a query in MySQL?

I want to write a query that can show the amount of purchases made in the month of June, grouped by city. So I wrote this query:
SELECT state, city, COUNT(*)
FROM address
JOIN person
JOIN purchase
WHERE purchase.person_FK = person.id
AND address.person_FK = person.id
AND MONTH(purchase.purchase_date) = 5
GROUP BY state, city
ORDER BY state, city;
But this query doesn't return the cities that have no purchases in that month, and I want to show them. Can you help me?
You need a city table with all the cities, then do a LEFT JOIN.
And put the JOIN condition on the ON section not the WHERE
SELECT Cities.state, Cities.city, COUNT(*)
FROM Cities
LEFT JOIN Purchase
ON Cities.city = Purchase.city
AND Cities.state = Cities.state
JOIN person
ON purchase.person_FK = person.id
AND MONTH(purchase.purchase_date) = 5
JOIN address
ON address.person_FK = person.id
GROUP BY Cities.state, Cities.city
ORDER BY Citiesstate, Cities.city;
Look at your joins, 'JOIN' is the same as 'INNER JOIN' which only shows results which is in both tables, you'll need to use a LEFT or FULL join to get what you need.
Theres a diagram here which explains them well
You will need to have a table that provides a listing of all cities you want to show (if you don't already have that). Then you join to the city table as well. Otherwise, your query has no idea which cities to show with a zero count. In addition, you will need to change your JOIN's to LEFT JOIN's
SELECT city.state, city.city, COUNT(*)
FROM address
LEFT JOIN person ON person.id = address.person_FK
LEFT JOIN purchase ON purchase.person_FK = person.id
LEFT JOIN city ON purchase.city = city.city
WHERE MONTH(purchase.purchase_date) = 5
GROUP BY address.state, address.city
ORDER BY address.state, address.city;

MySQL - writing joins to get data from many-layers linked tables

I'm having trouble writing the query for this specific task. Here are the simplified tables:
`job`: job_id, school_id
`school`: school_id, country_id
`country`: country_id, region_id
`region`: region_id, region
Now, I'm querying the job table to get the jobs listing, but I also need to show each job's region (i.e. Europe, Asia, etc.)
How do I do so giving these linked tables?
from what you provide it looks like this:
select
*
from `job` j
inner join `school` s on j.school_id = s.school_id
inner join `country`c on s.country_id = c.country_id
inner join `region` r on c.region_id = r.region_id
But I think the school table should hold region, or, country and region.

I want to select a specific data, but query result gives all column in sqlite

I have a little problem. I am beginner on database.
I want to select Country_Code from table2, using Country_Name column from table 1.
SELECT Country_Code FROM COUNTRIES, COUNTRY_SMALL_INFO WHERE COUNTRIES.Country_Name = 'Belgium'
I tried to get only country code of Belgium, but I got all Country_Code column.
This is the result.
http://i.stack.imgur.com/6sFRu.png
You should bind COUNTRIES with COUNTRY_SMALL_INFO somehow. Maybe they have id columns? If so your query could be
SELECT Country_Code
FROM COUNTRIES, COUNTRY_SMALL_INFO
WHERE COUNTRIES.ID = COUNTRY_SMALL_INFO.ID AND COUNTRIES.Country_Name = 'Belgium'
You forgot to JOIN both tables, so it is doing a cartesian product. Also use DISTINCT to have unique set of country_code. Try something like this
SELECT DISTINCT i.Country_Code
FROM COUNTRIES c
INNER JOIN COUNTRY_SMALL_INFO i ON c.id = i.country_id
WHERE c.Country_Name = 'Belgium'

Mysql query using IN with group_concat result

I'm trying to clean a db with duplicate records. I need to move the reference to a single record and delete the other one.
I have two tables: Promoters and Venues, each has a reference to a table called cities. The problem is that there are cities with the same name and different ids, that have a relation with venues and promoters.
With this query I can group all promoters and venues with a single city record:
SELECT c.id as id, c.name as name, GROUP_CONCAT( DISTINCT p.id ) as promoters_ids, GROUP_CONCAT( DISTINCT v.id ) as venues_ids
FROM cities as c
LEFT JOIN promoters as p ON p.city_id = c.id
LEFT JOIN venues as v ON v.city_id = c.id
WHERE c.name IN ( SELECT name from cities group by name having count(cities.name) > 1 )
GROUP BY c.name
Now I want to run an UPDATE query on promoters, setting the city_id equals to the result of the query above.
Something like this:
UPDATE promoters AS pr SET pr.city_id = (
SELECT ID
FROM (
SELECT c.id as id, c.name as name, GROUP_CONCAT( DISTINCT p.id ) as promoters_ids
FROM cities as c
LEFT JOIN promoters as p ON p.city_id = c.id
WHERE c.name IN ( SELECT name from cities group by name having count(cities.name) > 1 ) AND pr.id IN promoters_ids
GROUP BY c.name
) AS T1
)
How can I do this?
Thanks
If I understand correctly, you want to remove duplicate cities (in the end), so you need to update promoters that are linked to any of the cities you want to remove in that process.
I think it makes sense to use the lowest ID of any of the cities with the same name (could be the highest just as well, but I want to specify it at least, and don't leave it up to me.
So in order get the right ID for a promoter, I need to: Select the lowest ID of all cities that have the same name as the city already linked to a promoter.
Fortunately, that demand fits snuggly into a query:
UPDATE promoters AS pr
SET pr.city_id = (
SELECT
-- Select the lowest ID ..
Min(c.id)
FROM
-- .. of all cities ..
Cities c
-- .. that have the same name ..
INNER JOIN Cities pc on pc.Name = c.Name
WHERE
.. as the city already linked to the promoter being updated
pc.id = pr.city_id
GROUP BY
c.name)
The trick is to join Cities on itself by name, so you can easily get all cities with the same name. I think you tried the same with the IN clause, but that's a little more complex than it needs to be.
I don't think you need group_concat at all, besides checking if the inned query returns the correct cities indeed, although it doesn't make sense, since you're already grouping on the name. When written like this, you can tell that there should be no way that this can go wrong:
SELECT
-- Select the lowest ID ..
MIN(c.id) AS id,
GROUP_CONCAT(c.name) AS names --< already grouped by this, so why...
FROM
-- .. of all cities ..
Cities c
-- .. that have the same name.
INNER JOIN Cities pc on pc.Name = c.Name
GROUP BY
c.name
I hope I understood the question correctly.