How to apply join on three tables? - sql

I have three tables customer, address, and city and I want to find the city each customer is from. So I am using two joins but after the query execution I find out that no two customers have the same city according to my query can someone please help me is my query ok.
I am using pagila database.
select c.first_name , ct.city
from customer c
join address a on c.address_id=a.address_id
join city ct on a.city_id=ct.city_id

Is this what are you expecting?
select distinct c.first_name , ct.city from customer c
join address a on c.address_id=a.address_id
join city ct on a.city_id=ct.city_id

Related

Joining tables and sum by attribute

I need to know how many employees does each company have for each country they are present in? I have to join two tables (companies and cities) and sum number of employees for each country.
SELECT *, SUM(EMPLOYEES)
FROM COMPANIES WHERE
JOIN CITIES
ON COMPANIES.CITYNAME = CITIES.CITYNAME
doesn´t work...
Tables to join and sum employees for each country
A couple of tips,
Try to alias your joins so your not typing the full table names in your join statements
Add a group by on every field your not aggregating on for your sum to work
SELECT CI.COUNTRYNAME,CO.CITYNAME,CO.COMPANYNAME,CI.POPULATION,CI.COUNTRYNAME,
SUM(EMPLOYEES) AS TOTAL_EMPLOYEES
FROM COMPANIES AS CO
JOIN CITIES AS CI
ON CO.CITYNAME = CI.CITYNAME
GROUP BY CI.COUNTRYNAME,CO.COMPANYNAME,CO.CITYNAME,CI.POPULATION
https://rextester.com/DLZNT87647

Oracle SQL - How do i select tables with 0 or more values from other tables

Soo i need to make a consult that shows the id of the city, name, and how much clients that city have including cities that have 0 clients;
I was first trying to just get the cities that have clients but have no ideia on how to include cities that have no clients.
I have a table: CITIES that cointains ID_city, NAME, and REGION
and the table: CLIENTS that cointains ID_client, NAME and ID_city
query:
select l.name, l.ID_city, count(c.name) from clients c
JOIN cities l on l.ID_city = c.ID_city
GROUP BY l.name, l.ID_city;
use left join
select l.nomecidade, l.codcidade, count(c.nomecliente) from prova.clientes c
left JOIN prova.cidades l on l.codcidade = c.codcidade
GROUP BY l.nomecidade, l.codcidade
Use left join but make sure which table you considering first.
The code below should solve the problem:
select C1.name, C1.ID_city, count(C2.name) from cities C1
LEFT JOIN clients C2 on C1.ID_city = C2.ID_city
GROUP BY C1.name, C1.ID_city;

Combining distinct and count() from two tables

I have two tables:
Customers (name, address, postcode (FK))
Postcodes (postcode (PK), county)
I want to find out how many customers are in each county.
I am assuming I need an inner join on postcode but don't know how to combine this with a count(customer_id) and distinct(county).
Although you can write queries with SELECT DISTINCT country it prevents you from doing aggregates such as COUNT. Instead you can use GROUP BY which broadly has the same effect as DISTINCT but with much more power and flexibility.
These two queries give the same results, but the second lets you then go on to add your JOIN and COUNT statements.
SELECT DISTINCT county FROM postcodes
SELECT county FROM postcodes GROUP BY county
By and large, don't use SELECT DISTINCT, but use this kind of pattern...
SELECT
postcodes.county,
COUNT(customers.customer_id)
FROM
postcodes
INNER JOIN
customers
ON customers.postcode = postcodes.postcode
GROUP BY
postcodes.county
Just join the Customers table to the Postcodes table on the common field 'postcode '. Then you can use Group By to get your counts and return one row per County
SELECT
County,
COUNT(Customer_Id) CustomerCount
FROM
Postcodes pc
JOIN Customers c ON pc.PostalCode = c.PostalCode
GROUP BY
County

SQL join beween tables with if statement

Say, I have the following two tables:
Table customer:
id, salutation, forename, lastname, companyID
and a table company:
Company_id, Company_name, Company_address
and I want to have an evaluation over all users and their company (if they belong to one)
salutation, forename, lastname, companyName
that would amount basically to a very easy script:
select salutation, forename, lastname, company_name
from customer, company
where companyID=Company_id;
The trouble now is just, that companyID can be null. (A customer doesn't need to be part of a company). And since there is no companyID null entry in the company table and any customer who has no company ID listed is omitted due to the joint statement.
Of couse I could divide it into two scripts one for companyid=null and one for not null and mix them with a UNION command, but is there perhaps something like an if statement?
something like:
select salutation, forename, lastname, placeholder
from customer, company
where
if companyID=null then placeholder=null
else (companyID=Company_id and placeholder=company_name);
?
I know there is a case statement, that can check on the field's value and return something else instead, but is there a way to combine that with a joint to another table?
You are looking for an outer join:
select cu.salutation, cu.forename, cu.lastname, co.company_name
from customer cu
left join company co on cu.companyID = co.Company_id;
In general you should stop using the ancient implicit join syntax in the where clause and use an explicit JOIN operator. That is also the only cross-DBMS way to actually do an outer join (all DBMS that supported some proprietary outer join syntax have deprecated that)
Try this
select salutation, forename, lastname, placeholder
from customer, company
where
(companyID=null and placeholder=null )
OR
(companyID=Company_id and placeholder=company_name);
Use a left join instead of an inner join
select a.salutation, a.forename, a.lastname, a.company_name
from customer a
left outer join company b
on a.companyID=b.companyID;

Subqueries on subqueries

I'm trying to create a select statement
I need to gather from one table a record that equals the same code used in another table.
better put, a client selects from a drop down list a city and a category for that city.
When the client clicks next, the various places in that city that meet that category are displayed.
but I can't figure out where I'm going wrong.
now when the client selects a city, there are two records that read for each city, a proper city code and a post box code that has 'bx' as the first letters
in my first query, to eliminate duplicates, I say
select c.[Description] from city c
where c.Provincecode like 'EC' and
c.citycode in (select c.citycode from City c
where SUBSTRING(c.citycode,0,3) not like 'bx')
that gives me one city name.
but now, if the client has chosen, for instance, cash only places to see,
there should only be one record showing up in the results
but try as I might, I can't get the right syntax
I've tried:
select c.[Description] from city c
where c.Provincecode like 'EC' and
c.citycode in (select c.citycode from City c
where SUBSTRING(c.citycode,0,3) not like 'bx')
and exists (select * from Customers cu
where cu.Category like 'SC' and cu.Province like 'EC')
but that brings more results than anticipated
this is done using an access database, but I am using SQL to do the coding, which I re-write into access. that's not a problem
so if someone could please provide the SQL answer, I can do the rest from there
I'm not sure if I'm supposed to do a join.
I did try
select * from
(select c.[Description] from city c
where c.Provincecode like 'EC' and
c.citycode in (select c.citycode from City c
where SUBSTRING(c.citycode,0,3) not like 'bx')) x
join Customers on province=city.provincecode where Category like 'SC'
but I get errors for multi-part identifier could not be bound
EDIT
this is the new query
select *
from
(
select c.*
from city c
where c.Provincecode like 'EC'
and c.citycode in
(
select c.citycode
from City c
where SUBSTRING(c.citycode,0,3) not like 'bx'
)
) x
join
Customers
on province=x.Provincecode
where Category like 'SC'
what is returned is
as you can see, there are too many reults that have C Strydom as the customer, but all the cities are there
for this particular example, only one record should be shown, the second one
The issue was an incomplete JOIN (see question comments for details). The query that worked was
select *
from
(
select c.*
from city c
where c.Provincecode like 'EC'
and c.citycode in
(
select c.citycode
from City c
where SUBSTRING(c.citycode,0,3) not like 'bx'
)
) x
INNER JOIN
Customers
ON Customers.province=x.Provincecode
AND Customers.city=x.Citycode
where Category like 'SC'
Although I don't like using SELECT *, you know more of the actual columns you DO want, I leave that to you. The query should be simple as you are primarily looking at the "City" table for a specific province code but doesn't start with "bx". Just have that in your where clause... you can test multiple things about a record without having to join to itself on some other criteria. Once you have that, then a simple join to the customer table for the category you are limiting to.
select *
from
city c
JOIN Customers CU
on c.ProvinceCode = CU.Province
AND CU.Category like 'SC'
where
c.ProvinceCode like 'EC'
and NOT substr( c.CityCode,0,3 ) = 'bx'
Now, your issue of the multiple records per customer. If all you are joining on is the province code to the customer table, you WILL get a Cartesian result... but if you join to the ProvinceCode AND City of the customer, you'll get only the single one that matches... but we don't have the customer table detail to confirm that column relationship.