Using the Oracle HR schema, how to display the amount of employees in each country? - oracle11g

This is my query.
SELECT country_name, COUNT(*) as num_employees
FROM employees
JOIN departments ON employees.department_id = departments.department_id
JOIN locations ON departments.location_id = locations.location_id
JOIN countries ON locations.country_id = countries.country_id
GROUP BY country_name;
OUTPUT
COUNTRY_NAME NUM_EMPLOYEES
---------------------------------------- -------------
United Kingdom 35
United States of America 68
Germany 1
Canada 2
I tried to display the amount of employees in each country, but it didn't display every countries.

It seems that not all countries (in your schema) have locations/departments/employees. In that case, you should use outer join, e.g.
SELECT c.country_name, COUNT (*) AS num_employees
FROM countries c
LEFT JOIN locations l ON l.country_id = c.country_id
LEFT JOIN departments d ON d.location_id = l.location_id
LEFT JOIN employees e ON e.department_id = d.department_id
GROUP BY c.country_name;

Related

UNION operator does not return any results in SQLite

I am working in SQLite and trying to make a query to return a table containing top five jobs in each of four regions (coastal, alpine, regional and metro) based on their respective incomes.
Each SELECT statement for a specific region returns correct result however, appending these separate results in one table using UNION does not return any table where UNION is underlined in red:
--
select job,
-- income as "Top_incomes",
1 as "income",
region.name
from customers
JOIN customer_region on customers.id = customer_region.customer_id
JOIN region on region.id = customer_region.region_id
where region.name = "regional"
ORDER by income DESC limit 5;
UNION
select job,
-- income as "Top_incomes",
2 as "income",
region.name
from customers
JOIN customer_region on customers.id = customer_region.customer_id
JOIN region on region.id = customer_region.region_id
where region.name = "coastal"
ORDER by income DESC limit 5
Although the number of columns per each statement is 3 and they all have the same column names for each statement, I am not sure why UNION does not return any result as a single table. Is there any wrong query syntax here? Thanks
--
select job,
-- income as "Top_incomes",
1 as "income",
region.name
from customers
JOIN customer_region on customers.id = customer_region.customer_id
JOIN region on region.id = customer_region.region_id
where region.name = "regional"
ORDER by income DESC limit 5;
UNION
select job,
-- income as "Top_incomes",
2 as "income",
region.name
from customers
JOIN customer_region on customers.id = customer_region.customer_id
JOIN region on region.id = customer_region.region_id
where region.name = "coastal"
ORDER by income DESC limit 5
I was expecting to get a single table containing results from each SELECT statement: 5 top-income jobs from the 'regional' region followed by the 5 top-income jobs from the 'coastal' region. I did not get any results back.
In a union query, the outermost ORDER BY clause applies to the entire query, not any individual select. You may use the following syntax:
SELECT *
FROM
(
SELECT job,
income AS Top_incomes,
1 AS income,
r.name
FROM customers c
INNER JOIN customer_region rc ON c.id = cr.customer_id
INNER JOIN region r ON r.id = cr.region_id
WHERE r.name = 'regional'
ORDER BY income DESC
LIMIT 5
)
UNION
SELECT *
FROM
(
SELECT job,
income,
2,
r.name
FROM customers c
INNER JOIN customer_region cr ON c.id = cr.customer_id
INNER JOIN region r ON r.id = cr.region_id
WHERE r.name = 'coastal'
ORDER BY income DESC
LIMIT 5
);

How do I include all max values within a row?

I'm very new to learning SQL, I apologize if my question isn't completely accurate.
The question I'm trying to answer with this query is "What is the most popular music genre in each country?" I've had to use a subquery and it works, but I found that for a few countries in the table, more than one genre has the MAX value. I'm stuck with how to edit my query so that all genres with the max value show in the results. Here is my code, using DB Browser for SQLite:
SELECT BillingCountry AS Country , name AS Genre , MAX(genre_count) AS Purchases
FROM (
SELECT i.BillingCountry, g.name, COUNT(g.genreid) AS genre_count
FROM Invoice i
JOIN InvoiceLine il
ON il.InvoiceId = i.InvoiceId
JOIN TRACK t
ON il.trackid = t.TrackId
JOIN Genre g
ON t.genreid = g.GenreId
GROUP BY 1,2
) sub
GROUP BY 1
Here is an example of the result:
| Country | Genre |Purchase|
|---------|-------|--------|
|Agrentina| Punk | 9 |
|Australia| Rock | 22 |
BUT in running just the subquery to COUNT the purchases, Argentina has two Genres with 9 Purchases (the max number for that country). How do I adjust my query to include both and not just the first one in the row?
You can do it with RANK() window function:
SELECT BillingCountry, name, genre_count
FROM (
SELECT i.BillingCountry, g.name, COUNT(*) AS genre_count,
RANK() OVER (PARTITION BY i.BillingCountry ORDER BY COUNT(*) DESC) rnk
FROM Invoice i
INNER JOIN InvoiceLine il ON il.InvoiceId = i.InvoiceId
INNER JOIN TRACK t ON il.trackid = t.TrackId
INNER JOIN Genre g ON t.genreid = g.GenreId
GROUP BY i.BillingCountry, g.name
)
WHERE rnk = 1
This will return the ties in separate rows.
If you want 1 row for each country, you could also use GROUP_CONCAT():
SELECT BillingCountry, GROUP_CONCAT(name) AS name, MAX(genre_count) AS genre_count
FROM (
SELECT i.BillingCountry, g.name, COUNT(*) AS genre_count,
RANK() OVER (PARTITION BY i.BillingCountry ORDER BY COUNT(*) DESC) rnk
FROM Invoice i
INNER JOIN InvoiceLine il ON il.InvoiceId = i.InvoiceId
INNER JOIN TRACK t ON il.trackid = t.TrackId
INNER JOIN Genre g ON t.genreid = g.GenreId
GROUP BY i.BillingCountry, g.name
)
WHERE rnk = 1
GROUP BY BillingCountry

SQL Query: Select the sum(quantity) and count(number) SQLite

I am trying to query the chinnok database to select sum of quantity tracks purchase and count the number of times the track appears in a playlist in one query.
Here is what I have:
/* Query 3 : which artist has the most songs on the top 100 songs across playlist and the most sold
songs*/
SELECT ar.Name Artist_Name, tr.Name Track_Name, count(pl.Name) Play_List, pt.TrackId Track_ID,
SUM(il.Quantity) Qty,
CASE WHEN count(pl.Name)=5 THEN "Five Stars"
ELSE "Four Star" END AS Ranking
FROM Track tr
JOIN PlaylistTrack pt
ON pt.TrackId = tr.TrackId
JOIN Playlist pl
ON pl.PlaylistId=pt.PlaylistId
JOIN Album ab
ON ab.AlbumId = tr.AlbumId
JOIN Artist ar
ON ar.ArtistId = ab.ArtistId
JOIN InvoiceLine il
ON il.TrackId = tr.TrackId
GROUP BY tr.TrackId
ORDER BY Play_List DESC
LIMIT 100;
Here is the results:
Fist 6 results
First 16 results
The Qty is correct but the Play_list number is not.
Can anyone help?

Correct way to get aggregate value with group by

I have 2 tables such as Customers and Purchases tables. And I try to get the customers who made more than 1 purchase in a certain year. So this is my current query
select c.name, c.email
from customers c inner join purchases p
on c.customerid = p.customerid
where p.year = 2002
group by c.name, c.email
The problem I am having right now is this query will result whoever make a purchase which is not exactly what I want. So I want to edit as:
select c.name, c.email
from customers c inner join purchases p
on c.customerid = p.customerid
where p.year = 2002 and p in
(select p.customerid, count(p.*) as total
from purchases
where total > 1
group by p.customerid)
group by c.name, c.email
And this query is full a syntax error. Some one help to give me an idea please.
May be something like this
SELECT C.Name, C.Email
FROM Customers C INNER JOIN Purchases P ON C.CustomerID = P.CustomerID
WHERE P.Year = 2002
GROUP BY C.Name, C.Email
HAVING COUNT(P.CustomerID) > 1
SELECT *
FROM Customers
WHERE (SELECT COUNT(*)
FROM Purchases
WHERE Year = 2002
AND CustomerID = Customers.CustomerID) > 1

Show name of a country in three fields

I have a table called Principal with these columns:
Person_ID
Country1_ID
Country2_ID
Country3_ID
And I have another table called Countries with these columns:
ID
Country_Name
I need make a select that shows the Person_ID and the name of the three countries.
I have try with INNER JOIN, but always give me the same country in the three fields.
SELECT Principal.Person_ID, Countries.Country_Name AS Country1, Countries.Country_Name AS Country2, Countries.Country_Name AS Country3
FROM
(Countries
INNER JOIN Principal
ON Countries.ID = Principal.Country1_ID OR Countries.ID = Principal.Country2_ID OR Countries.ID = Principal.Country3_ID);
What is the right SELECT?
I think this will get you want you want. It returns blank when a country does not match.
SELECT Principal.Person_ID
,(SELECT ISNull(Countries.Country_Name,'') FROM Countries WHERE Principal.Country1_ID OR Countries.ID ) AS Country1
,(SELECT ISNull(Countries.Country_Name,'') FROM Countries WHERE Principal.Country2_ID OR Countries.ID ) AS Country2
,(SELECT ISNull(Countries.Country_Name,'') FROM Countries WHERE Principal.Country3_ID OR Countries.ID ) AS Country3;
A merge might work better but I'm not so familiar with them.

Resources