Count the repeats of foreign key of two tables - sql

I have two tables Countries( id, country) and Cities (id, city, countryId ) I want to select countries and to show how much cities AS locations .
I tried this :
SELECT countryid, COUNT(*) AS locations
FROM Cities
GROUP BY countryid
but it shows me countryid instead of country

You need to join the tables as follows:
select c.country, count(*) as locations
from Country c
inner join Cities ci
on c.id = ci.countryId
group by c.id, c.country
I also included the country in the group by since it appears in the select clause

Related

How do I count something the number of employee that is in a different table in SQL?

The question asks
"Write a query to display the city and country where an office is located and a count of the number of employees at that location. Order the results in descending order of the number of employees."
So far I have put,
SELECT city, country, SELECT COUNT(city,country)
FROM Offices
ORDER BY(SELECT COUNT(city,country)
FROM Offices)DESC;
It wont let me run it however. I reckon I made a mistake in the SELECT COUNT part.
The employees table contains
employeeNumber
lastName
firstName
extension
email
reportsTo
jobTitle
officeCode
The Office table contains
officeCode
city
phone
addressLine1
addressLine2
state
country
postalCode
territory
officeLocation
Anyone know what I'm doing incorrectly? Thank you! Sorry if this is a lot of stuff.
You can do it using a LEFT JOIN, GROUP BY and ORDER BY.
We need LEFT JOIN and GROUP BY to get the employee count and the ORDER BY to order the results in descending order of no of employees.
SELECT OfficeCode, City, Country, COUNT(E.employeeNumber) AS EmployeeCount
FROM Offices O
LEFT JOIN Employees E ON E.OfficeCode = E.OfficeCode
GROUP BY OfficeCode, City, Country
ORDER BY COUNT(E.employeeNumber) DESC
use join and count
SELECT city, country,officeLocation, COUNT(e.employeeNumber)
FROM Offices ofc join employees e on ofc.officeCode=e.officeCode
group by city, country,officeLocation
A couple ways to tackle this. Using a LEFT OUTER JOIN: (make sure to use a LEFT OUTER and not an INNER JOIN here or else you will only get locations with employees. That may work in your case but what if a location has no current employees?)
SELECT City, Country, COUNT(e.employeeNumber) AS EmployeeCount
FROM Offices o
LEFT OUTER JOIN Employees e
ON e.OfficeCode = o.OfficeCode
GROUP BY City, Country
ORDER BY 3 DESC
Or you could use a subquery with the select statement:
SELECT City, Country,
(SELECT COUNT(*) FROM Employees e WHERE o.OfficeCode = e.OfficeCode) AS EmployeeCount
FROM Offices o
ORDER BY 3 DESC

UNION vs. JOIN, b and c not defined? (sqlite3)

select city, prov, a, b, c from (
select count(city) as a, city, prov from locations left outer join rides on src=lcode
group by city
union
select count(city) as b, city, prov from locations left outer join rides on dst=lcode
group by city
union
select count(city) as c, city, prov from locations l left outer join enroute e on l.lcode=e.lcode
group by city
) group by city;
So I got an error saying "no such column: b" (and also column c). Is it possible to solve this without changing a lot of this query?
Your subquery is returning three columns, a, city, and prov. That is, for a union/union all query, the column names come from the first subquery. There is no b or c.
Presumably, you want some sort of JOIN, not UNION ALL. However, your question does not explain what you are trying to do. And it doesn't have sample data or desired results. So, it is really hard to say what you actually want.
It strikes me that you actually want:
select city, prov, sum(a), sum(b), sum(c)
from ((select city, prov, count(city) as a, null as b, null as c
from locations left outer join
rides on src = lcode
group by city
) union all
(select city, prov, null, count(city), 0
from locations left outer join
rides
on dst = lcode
group by city
) union all
(select city, prov, null, null, count(city)
from locations l left outer join
enroute e
on l.lcode = e.lcode
group by city
)
) abc
group by city;
The expressions that are not encapsulated within an aggregate function and must be included in the GROUP BY clause. For Unions, all of the select statements in those unions must have the same column names.
Below would do the required tasks.
select * from (
select count(city) as cityCount, prov from locations left outer join rides on src=lcode
group by prov
union
select count(city) as cityCount, prov from locations left outer join rides on dst=lcode
group by prov
union
select count(city) as cityCount,prov from locations l left outer join enroute e on l.lcode=e.lcode
group by prov
);
Doesn't require an additional groupby for Outside subquery. It will already be grouped by provinces of locations.

SQL, choosing maximum values from another table

This one I've been spending the last hours on. Still haven't found an answer so I figured I'd ask.
I have two tables:
Country - Code, Name, Populaion.
City - CountryCode, Name, Population.
The Foreign key is the CountryCode which response to country.Code.
I'm trying to find the most populated city in each country, where the output is the name of the country and the city. I know this could be done with Max(), but I'm having a struggle limiting my table to showing all the countries name and showing onle the name of the most populated city.
SELECT country.name, city.name, MAX(city.Population)
FROM city
LEFT JOIN country
ON city.CountryCode=Country.Code
GROUP BY city.name, country.name, city.population
ORDER BY city.population DESC;
This only gives me all the countries and all the cities. Could anyone help me narrow it down so it only shows every countries name but with their largest city?
You want to first the max population in each country and then join it with the city table to know which city it belongs to. After that, join it with the country table to get the required result.
select co.name,
ct.name,
ct.population
from (
select c1.*
from city c1
join (
select countryCode,
max(population) population
from city
group by countryCode
) c2 on c1.countryCode = c2.countryCode
and c1.population = c2.population
) ct
join country co on ct.countryCode = co.code;
Another way of finding max in group using left join:
select co.name,
ct.name,
ct.population
from (
select c1.*
from city c1
left join city c2 on c1.countryCode = c2.countryCode
and c1.population < c2.population
where c2.countryCode is null
) ct
join country co on ct.countryCode = co.code;

Retrive counts of two columns from two diffrent tables with third table using join query in SQL

I have 3 tables: COUNTRY, STATE, CITY
This is my Country table with two columns:
CountryID, Name
This is my State table:
This is my City table:
I want to retrieve the count of states and cities according to the country table using join query.
Skipping the fact that your question is not asked well - try this query, it should work for you:
WITH
tab_a AS (
SELECT c.countryid, COUNT (s.stateid) AS state_num
FROM country c
LEFT JOIN state s ON c.countryid = s.countryid
GROUP BY c.countryid
),
tab_b AS (
SELECT c.countryid, COUNT (cc.cityid) city_num
FROM country c
LEFT JOIN state s ON c.countryid = s.countryid
LEFT JOIN city cc ON s.stateid = cc.stateid
GROUP BY c.countryid
)
SELECT a.countryid,
a.state_num,
b.city_num
FROM tab_a a JOIN tab_b b ON a.countryid=b.countryid

SQL query - IS NULL

Tables:
Country
-------
PK CountryID
Name
City
-------
PK CityID
FK CountryID
Name
Airport
--------
PK AirportID
FK CityID
Name
My task is to select names of countries that have no airport.
I can imagine only one solution with EXCEPT (or MINUS)
SELECT Country.Name
FROM Country EXCEPT (SELECT DISTINCT Country.Name FROM Country, City, Airport
WHERE City.CountryID = Country.CountryID AND Airport.CityID = City.CityID);
But is it possible not to use EXCEPT but something like IS NULL?
SELECT cn.CountryID
FROM Country cn
LEFT JOIN City ct ON cn.CountryID = ct.CountryID
LEFT JOIN Airport ar on ar.CityID=ct.CityID
WHERE ar.AirportID is null
If you need to make this query with IS NULL try following query:
SQLFiddle demo
select ct.CountryId,max(ct.Name) from Country ct
left join City c on ct.CountryId=c.CountryId
left join Airport a on a.CityId=c.CityID
group by ct.CountryId
HAVING max(a.AirportID) IS NULL
You can use this, but it's basically the same thing you have with different syntax.
SELECT Country.Name
FROM Country
Where Country.Name Not IN
(
SELECT DISTINCT Country.Name FROM Country, City, Airport
WHERE City.CountryID = Country.CountryID AND Airport.CityID = City.CityID
);