SQL query using table aliases - mysql

I have a created a table named city in my database. This table has 2 columns, called 'name' and 'country'. I have created a query that returns the combinations of cities from different countries which is below:
SELECT c1.name, c1.country, c2.name, c2.country
FROM city c1, city c2
WHERE c1.country != c2.country
This query works, but however the city pairs are repeated ie. I get results with:
Berlin Germany London England
London England Berlin Germany
which means that the city pair berlin/hamburg is repeated in my result set. Is there a way around this?

SELECT c1.name, c1.country, c2.name, c2.country
FROM city c1, city c2
WHERE c1.country < c2.country

You can do this by using LEFT JOIN see Visual Explanation Of Joins try this:
SELECT c1.name, c1.country, c2.name, c2.country
FROM city c1
LEFT JOIN city c2
ON c1.country = c2.country
AND c1.name = c2.name
WHERE c1.country IS NULL OR
c2.country IS NULL;

A good database will never have two or more same records in a single table. So my recommendation is two make 2 tables:
cities: ID, country_ID, Name
countries: ID, Name
and the select should be:
SELECT c.Name, co.Name
FROM cities c
INNER JOIN countries co
ON co.ID=c.country_ID

Related

How to JOIN 2 SELECT statements but only show output when conditions from table A are met on table B

I'm practicing views and I need to JOIN two tables, (the easiest way) but on table A I have like 6 rows when conditions are met, and on table B with the same conditions regarding table B (same column name), like 82.
I need to show only the data regarding those 6 rows.
CREATE VIEW myview AS
SELECT Name AS Country, Population FROM country WHERE Population >= 9000000;
SELECT District, Name AS City, Population FROM city WHERE Population >= 9000000;
Im working with the world database.
_________________City_________________
ID | Name | CountryCode | District | Population
_________________Country_________________
Name | Population | Code
Sample data:
City
Country
Expected result:
Cheers.
if you want a view that join the two table you could use
CREATE VIEW myview AS
SELECT co.Name AS Country
, co.Population Country_population
, ci.District
, ci.Name As city
, ci.population City_population
FROM country co
INNER JOIN city ci ON ci.CountryCode = co.Code
WHERE ci.population >= 9000000
then
select * from myview;
From your expected results I assume that you want for each country the city/cities with population >= 9000000, so join like this:
select
c.Name country,
t.district,
t.city,
t.population
from country c inner join city t
on t.countrycode = c.Code
where t.population >= 9000000;
You don't need to set the condition population >= 9000000 for the country too because a country with a city with population >= 9000000 surely satisfies that condition.

The correct mysql statement for linking countys to the only locations with document

I have 3 tables in the a db.
1 location (location_id, county_id, name)
2 county (county_id, name)
3 document (document_id, document_type, location_id, title, text)
The sql statement I have:
SELECT d.document_id, d.title, l.name AS location_name
FROM document d
INNER JOIN location l ON d.location_id=l.location_id
WHERE d.document_type = 1 AND d.title LIKE '%foo%'
I need the document title and id, the location name and location_id, and the county name and county_id to be returned.
The question is how can I select the county names and county_id for only the locations I have a in this result and not for all locations in location table.
If I do another INNER JOIN county c ON l.county_id=c.county_id, then the query is taking to long, with adding counties for all locations (There are 13.000 locations in the table).
select * from country where country_id in (
SELECT country_id
FROM document d
INNER JOIN location l ON d.location_id=l.location_id
WHERE d.document_type = 1 AND d.title LIKE '%foo%')

I need a sql query to view data

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.

MySql - Find values that occur AT LEAST two times without using any aggregate function

Table:City
City_Name (PK) State_Name (PK) Population
-------------- --------------- ----------
Austin MA
Austin TX
Burlington VT
Fresno CA
Houston TX
Independence KS
Independence MO
Independence PA
Kansas CA
Kansas MO
Paris MO
Paris OR
Paris TX
Paris VA
Paso TX
The above table has a composite primary key (City_Name and State_Name). I want to find the city which occur in at least two distinct States. In this case, the result will be
City_Name
---------
Austin
Independence
Kansas
Paris
Other cities will not qualify as they don't occur in at-least two states.
This solution is required for practicing relational calculus problems and thus (unfortunately) aggregate function such as COUNT() cannot be used. I went through a database book where I saw a solution to similar problem which looks like this, but not working.
SELECT c1.State_Name FROM City AS c1
JOIN City AS c2 on c1.City_Name = c2.City_Name AND c1.State_Name = c2.State_Name
JOIN City AS c3 on c1.City_Name = c3.City_Name AND c1.State_Name = c3.State_Name
WHERE (c2.City_Name<>c3.City_Name) AND (c2.State_Name<>c3.State_Name);
Some help at this point will be highly welcoming.
You can use COUNT(DISTINCT) and restrict your result with the HAVING clause:
SELECT City_Name, COUNT(DISTINCT State_Name)
FROM City
GROUP BY City_NAME
HAVING COUNT(DISTINCT State_Name) > 1
see documentation of COUNT(DISTINCT)
Returns a count of the number of rows with different non-NULL expr values.
I overlooked the restriction not be able to use COUNT(). That leads indeed to a self join:
SELECT
DISTINCT c1.City_Name
FROM
City c1
INNER JOIN
City c2
ON
c1.City_Name = c2.City_Name
AND
c1.State_Name <> c2.State_Name
Demo for both solutions.
If you can't use any kind of aggregate functions, then the following would return the cities that appear at least twice
SELECT distinct c1.city_name
FROM `city` c1
JOIN city c2
ON c1.city_name=c2.city_name
AND c1.state_name!=c2.state_name
I assumed that not only COUNT but also any kind of aggegate was unavailable
SELECT City_Name FROM City GROUP BY City_Name HAVING COUNT(City_Name) > 1;
You could use an exists subquery:
select city_name
from city c1
where exists
(
select *
from city c2
where c1.city_name = c2.city_name
and c1.state_name <> c2.state_name
)
SELECT city FROM mytable
GROUP BY city
HAVING count(city) > 1
SQLFiddle Demo

MySQL: SELECT and COUNT in same query

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