Joining SQL lookup table with data table - sql

I have a lookup table say cities with fields CityId, CityName
CityId CityName
1 New York
2 San Francisco
3 Chicago
I have an orders table which has fields: CityId, CustId, CompletedOrders, PendingOrders
CityId CustId CompletedOrders PendingOrders
1 123 100 50
2 123 75 20
I want a table/report that lists orders details of a given customer in all cities, i.e. the result I need is:
CityId CityName CustId CompletedOrders PendingOrders
1 New York 123 100 50
2 San Francisco 123 75 20
3 Chicago 123 0 0
How to do that ?

SELECT
c.CityId
c.CityName
o.CustId,
o.CompletedOrders
o.PendingOrders
FROM cities c
LEFT JOIN orders o ON ( c.CityId = o.CityId )
This will return all the rows that you want, but for the rows that don't exist in details it will return NULL values, so you would get:
CityId CityName CustId CompletedOrders PendingOrders
1 New York 123 100 50
2 San Francisco 123 75 20
3 Chicago 123 NULL NULL
The solution to get 0 instead depends on your database. With MySQL use IFNULL, with Oracle use NVL.

try this
select c.CityId,c.CityName,o.CustId,o.CompletedOrders,o.PendingOrders
from orders Left join cities
on o.CityId = c.CityId

Related

SQL to return one row from many

I have the following data
PersonId
City
Type
UpdateDate
123
Boston
P
01/01/2021
123
Boston
M
02/01/2021
130
Detroit
P
01/01/2021
130
Detroit
M
03/01/2021
140
Dallas
M
02/01/2021
140
Dallas
M
03/01/2021
I want a query that returns one row per PersonId. If the Type is "P" return that row otherwise return the row with the minimum UpdateDate. So the query would return:
PersonId
City
Type
UpdateDate
123
Boston
P
01/01/2021
130
Detroit
P
01/01/2021
140
Dallas
M
02/01/2021
In the past I would write a query like
select * from person, address
where person.PersonId = address.PersonId
group by PersonId
having (Type = 'P') or (UpdateDate = min(UpdateDate))
but this is not allowed anymore.
What should my SQL query be in SQL Server?
Presumably you want the most recent address per person. If so, outer apply is very well suited to this problem:
select p.* a.*
from person p outer apply
(select top (1) a.*
from address a
where a.PersonId = p.PersonId
order by (case when a.type = 'P' then 1 else 2 end),
a.updatedate desc
) a;
No aggregation is called for.

How group by count from multiple tables

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.

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;

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

Select Statement to return TaskID if column Exists in another table

I have two tables.
First table is called task the second table is named countries.
My task table
ID TaskID Country CustomerID
------------------------------------------
1 213 china 22
2 213 USA 24
3 213 china 26
4 214 Canada 28
Countries table
ID Country
---------------
1 USA
2 Japan
3 England
I need a select statement that returns all task ID's that doesnt have its country i the countries table.
In this case I would need to return TASKID: 214 because canada is not in the countries table. I would not get TASKID: 213 because USA is in the countries table.
Try this:
SELECT
TaskID
FROM
Task T LEFT OUTER JOIN Countries C ON (T.COUNTRY = C.COUNTRY)
GROUP BY
TaskID
HAVING
COUNT(C.ID) = 0
Try this,
select taskid
from task where taskid not in
(select taskid from task where country in
(select country from countries))
Try like this,
SELECT t.taskid
FROM task t
WHERE EXISTS (
SELECT 1
FROM countries
WHERE country = t.country
)