How group by count from multiple tables - sql

I have 3 different tables, country, city, and customer. Tables are shown below:
country table:
id country_name
1 UK
2 US
3 Brazil
:
n Canada
city table
id city_name postal_code country_id
1 London 30090 1
2 Dallas 20909 2
3 Rio 29090 3
4 Atlanta 30318 2
:
n Vancouver 32230 n
customer table
id customer_name city_id
1 John 1
2 Pete 3
3 Dave 2
4 May 2
5 Chuck 4
6 Sam 3
7 Henry 3
***country.id is references city.country_id, and city.id is references customer.city_id
I want to write a query that can extract the country name, city name and the count of the customer of the associate city. But with one condition, the query will return all cities with more customers than the average number of customers of all cities
It will look something like below, this is the correct output
UK London 2
Brazil Rio 3
but I kept getting this output, which isn't correct
UK London 2
US Dallas 2
US Atlanta 1
Brazil Rio 3
I fixed my SQL query but it doesn't give me the result that I want
SELECT country.country_name, city.city_name, COUNT(customer.city_id) from country
JOIN city on country.id = city.country_id
JOIN customer on city.id = customer.city_id
Group by city_name,country.country_name;
I am wondering how can I do this and fix my code?

add country.country_name in group by
SELECT country.country_name, city.city_name, COUNT(customer.city_id) from country
JOIN city on country.id = city.country_id
JOIN customer on city.id = customer.city_id
Group by city_name,country.country_name

You are missing country.country_name in the query it will give you error. As a general rule all columns on which aggregate function is not applied should be part of group by clause.
So either you write your query without country_name in the select or add country_name in the group by clause.

Related

How to replace multiple columns in one SQL query?

I have 2 tables: country and trip.
A trip can have up to 3 country codes.
country table
country_code
country_name
FRA
FRANCE
IRL
IRELAND
JPN
JAPAN
MAR
MOROCCO
NZL
NEW ZEALAND
trip table
trip_id
country_code
country_code2
country_code3
1
FRA
IRL
JPN
2
MAR
NZL
My goal is to have country names displayed on the trip table instead of country codes.
I succeed to have only 1 country code replaced, thanks to the left join clause. I would like to have up to 3 country names displayed per row.
SELECT trip_id, country_name
FROM trip
LEFT JOIN country ON country_code = country_name
The actual output of the trip table:
trip_id
country_name
1
FRANCE
2
MOROCCO
Is there a way to replace each country code with its corresponding country name?
The EXPECTED output of the query from the trip table:
trip_id
country_name
country_name2
country_name3
1
FRANCE
IRELAND
JAPAN
2
MOROCCO
NEW ZEALAND
Thank you!
You could add two more joins
SELECT trip_id, c1.country_name, c2.country_name, c3.country_name
FROM trip t
left join
country c1
on t.country_code = c1.country_code
left join
country c2
on t.country_code2 = c2.country_code
left join
country c3
on t.country_code3 = c3.country_code
The cleanest way of accomplishing this query is using subqueries:
SELECT t.trip_id,
(SELECT country_name FROM country WHERE country_code = t.country_code) "c1",
(SELECT country_name FROM country WHERE country_code = t.countty_code2) "c2",
(SELECT country_name FROM country WHERE country_code = t.country_code3) "c3"
FROM trip t

Sql join in two tables and return empty tab as Unavaliable

In a SQL join, table 1 contains person info with city and table 2 contains city matched to country such as:-
Table #1
ID Name City
-------------------------
1 Kishan Pokhara
2 Ram Delhi
3 Shyam Beijing
Table #2
City Country
----------------------
Pokhara Nepal
Delhi India
I want to get the person ID, Name, Country so while joining the tables I want these items and if there is no country available for a city, I want "Unavailable" written in the country columns. Thanks
Try the below using left join and use coalesce() function to replace null country as 'Unavailable'
select id, name, a.city,coalesce(country,'Unavailable') as country
from table1 a left join table2 b on a.city=b.city

SQL ordering cities ascending and persons descending

I have been stuck in complicated problem. I do not know the version of this SQL, it is school edition. But it is not relevant info now anyway.
I want order cities ascending and numbers descending. With descending numbers I mean when there is same city couple times it orders then biggest number first.
I also need row numbers, I have tried SELECT ROW_NUMBER() OVER(ORDER BY COUNT(FIRST_NAME)) row with no succes.
I have two tables called CUSTOMERS and EMPLOYEES. Both of them having FIRST_NAME, LAST_NAME, CITY.
Now I have this kind of code:
SELECT
CITY, COUNT(FIRST_NAME),
CASE WHEN COUNT(FIRST_NAME) >= 0 THEN 'CUSTOMERS'
END
FROM CUSTOMERS
GROUP BY CITY
UNION
SELECT
CITY, COUNT(FIRST_NAME),
CASE WHEN COUNT(FIRST_NAME) >= 0 THEN 'EMPLOYEES'
END
FROM EMPLOYEES
GROUP BY CITY
This SQL code gives me list like this:
CITY
NEW YORK 2 CUSTOMERS
MIAMI 1 CUSTOMERS
MIAMI 4 EMPLOYEES
LOS ANGELES 1 CUSTOMERS
CHIGACO 1 CUSTOMERS
HOUSTON 1 CUSTOMERS
DALLAS 2 CUSTOMERS
SAN JOSE 2 CUSTOMERS
SEATTLE 2 CUSTOMERS
SEATTLE 5 EMPLOYEES
BOSTON 1 CUSTOMERS
BOSTON 3 EMPLOYEES
I want it look like this:
ROW CITY
1 NEW YORK 2 CUSTOMERS
2 MIAMI 4 EMPLOYEES
3 MIAMI 1 CUSTOMERS
4 LOS ANGELES 1 CUSTOMERS
5 CHIGACO 1 CUSTOMERS
6 HOUSTON 1 CUSTOMERS
7 DALLAS 2 CUSTOMERS
8 SAN JOSE 2 CUSTOMERS
9 SEATTLE 5 EMPLOYEES
10 SEATTLE 2 CUSTOMERS
11 BOSTON 3 EMPLOYEES
12 BOSTON 1 CUSTOMERS
You can use window functions in the ORDER BY:
SELECT c.*
FROM ((SELECT CITY, COUNT(*) as cnt, 'CUSTOMERS' as WHICH
FROM CUSTOMERS
GROUP BY CITY
) UNION ALL
(SELECT CITY, COUNT(*), 'EMPLOYEES'
FROM EMPLOYEES
GROUP BY CITY
)
) c
ORDER BY MAX(cnt) OVER (PARTITION BY city) DESC,
city,
cnt DESC;

I wonder how it works when multiple group by, like group by column_name(1), column_name(2), column_name(3)

When i checked it, it doesn't remove duplication of value. Why?
example) Group by a , Group by a,b,c
Is there a difference between Group by a, Group by a,b,c ?
I wrote SQL query like this ::
SELECT COUNT(CustomerID), Country
FROM Customers
GROUP BY Country;
result ::
Table: Customers
COUNT(CustomerID) Country
---------------------------------
3 Argentina
2 Austria
2 Belgium
9 Brazil
3 Canada
2 Denmark
2 Finland
to
SELECT COUNT(CustomerID), Country
FROM Customers
GROUP BY Country, CustomerID;
Table: Customers
COUNT(CustomerID) Country
---------------------------------
1 Germany
1 Mexico
1 Mexico
1 UK
1 Sweden
1 Germany
1 France
Why doesn't tie same value changed query from Column_name?
It display all value along column_name.
I wonder if it works. thank you.

Check for an entry in SQL Server

-----------------------
country | city | ids
-----------------------
India Mumbai 1
India Chennai 2
India Kolkata 3
---------------------
USA New York 2
USA Utah 3
---------------------
I have given a sample from a table. From the table, I am trying to query all the countries without id 1. I wrote this(Country was not included in the Where condition since it needs to apply to all the countries of the table).
Select * from Countries
WHERE id<>1
I got this.
-----------------------
country | city | ids
-----------------------
India Chennai 2
India Kolkata 3
---------------------
USA New York 2
USA Utah 3
---------------------
But I need the output to contain only USA(which does not have id=1). Is there any workaround for this?
SELECT * from Countries WHERE country not in
(SELECT country from Countries WHERE id=1)
use NOT EXISTS
Select *
from Countries c
where not exists
(
select *
from Countries x
where x.country = c.country
and x.id = 1
)
You need to group by Country like below :
SELECT C.Country
FROM City
WHERE C.Country NOT IN
(SELECT country FROM City WHERE id=1)
SQL Fiddle Demo
OR
SELECT
C.Country
FROM
City C
GROUP BY C.Country
HAVING C.Country NOT IN
(
SELECT Country FROM City WHERE Id =1
)
SQL Fiddle Demo