Combining distinct and count() from two tables - sql

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

Related

How to apply join on three tables?

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

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

Multiple joins, average on one table, count on another

I have four tables in a database: City, User, CityRating, CityGreeting. The CityRating table has the UserID and CityID as the PK, and those are FKs to the USer and City table. The CityGreeting table has no PK, but has the UserID and CityID as FKs (the idea is that a user can greet a city as many times as desired, but only rate a city once).
I am trying to write a query that will return the average rating of the city overall, as well as the times a specific user greeted the city:
select City.CityID, City.CityName, City.CityStateOrProvince,
ROUND(AVG(Cast(RateCity.Rating as float)), 2) as AverageRating,
(select COUNT(HelloCity.CityID) from HelloCity where HelloCity.UserID like '<guid>') as TimesVisited
from City
right join RateCity
on City.CityID = RateCity.CityID
right join HelloCity
on City.CityID = HelloCity.CityID
group by City.CityID, City.CityName,
City.CityStateOrProvince, City.CityCountry, City.CityImageUri
Even if I can get this to work as expected (which it currently is not) I feel like it is really messy. In terms of best practices, would it be better to write two queries? This operation would be performed in an api, not sure if the performance would be better on writing two seperate queries instead, or one complex one like this. Any insight on this or how to get the query to work as expected?
***EDIT: Added picture to clarify: Average Rating is the average of all users who rated, and TimesVisited is the amount of times one specific user has visited the city.
I believe you need to aggregate the tables, apart from city separately for this to work correctly:
select c.*, rc.AverageRating, coalesce(hc.TimesVisited, 0) as TimesVisited
from City c join
(select CityId, ROUND(AVG(Cast(RateCity.Rating as float)), 2) as AverageRating
from RateCity rc
group by CityId
) rc
on c.CityID = rc.CityID left join
(select CityId, count(*) as TimesVisited
from HelloCity hc
where hc.UserID like '<guid>'
group by CityId
) hc
on c.CityId = hc.CityId;
Notes:
Table aliases make the query easier to write and to read.
I doubt you really mean right join. That would imply that there are CityIds in the other two tables that are not in City.
By doing the aggregation for each other table, you don't need an aggregation in the outer query.
I do think you want a left join for the HelloCity table, because not all cities might have visitors.
You might want a left join for the RateCity table as well, if not all cities have ratings.
why don't you use a CTE and then do the individual parts in each CTE, it helps to break it down instead of trying to mash together bunch of joins: for example:
DECLARE #userId VARCHAR(10) = 'userid1' ;
WITH
CITY_RATING_CTE (cityId, AverageRating) AS
( SELECT cityId,
AVG(Rating) AS rating
FROM RateCity
GROUP BY cityId),
TIMES_VISITED_CTE AS
( SELECT cityId,
count(*) AS TimesVisited
FROM HelloCity
WHERE UserId = #userId
GROUP BY cityId)
SELECT c.CityId,
c.CityName,
c.CityStateOrProvince,
c.CityImageUri,
cr.AverageRating,
tv.TimesVisited
FROM City c
JOIN CITY_RATING_CTE cr ON cr.cityId = c.CityId
JOIN TIMES_VISITED_CTE tv ON cr.cityId = cr.cityId;

oracle sql query to count based on another query

I want to know which customer from which country did the most orders. So I have a sales_table with the customer_ids. But the country_id is in the customer_table. So I need somehow to count the customers based on the country count... But I have no idea how to do it. I
I know how to count the customers.
select count(cust_id)
from sh_sales
and how to count the countries
select count(country_id)
from sh_customers
but i want to count the country based on the customer_id which is most often used in the sh_sales table
so it should somehow be
select count(country_id)
from sh_customers
where sh_sales.customer ????
I really need some help here :)
This will count the records in the sh_sales table and group out by each country_id from the customers table
SELECT country_id, count(s.cust_ID)
FROM sh_customers c
INNER JOIN sh_sales s ON c.cust_id = s.cust_id
GROUP BY country_id
If, for some reason, you could have a customer record, but no sales then you can use LEFT OUTER JOIN to return a NULL for countries without any sales

NHibernate Criteria Query - Select Distinct with Joined Entity

I have a Person entity. Every person has a country, I want to select all the distinct countries that have people in them. This Criteria Query returns all the distinct CountryID's
criteria.SetProjection(Projections.Distinct(Projections.Property("Country")));
How do I alter it to join and fetch the Country entity, not just the ID?
Any easy way would be to use a subquery. That is, you could select the whole country on the outer query where the country ID matches the inner query.
Subqueries.PropertyIn(
"Country",
innerDetachedCriteriaWhichFindsCountriesWithPeopleAndProjectsCountryId)