My goal is to find the top 10 countries within the top 10 cities. I successfully used this query:
SELECT
COUNT(A.customer_id) AS number_of_customers,
D.country, C.city
FROM
customer A
INNER JOIN
address B ON A.address_id = B.address_id
INNER JOIN
city C ON B.city_id = C.city_id
INNER JOIN
country D ON C.country_ID = D.country_ID
WHERE
country IN ('India', 'China', 'United States', 'Japan', 'Mexico', 'Brazil', 'Russian Federation', 'Phillipines', 'Turkey', 'Indonesia')
GROUP BY
C.city, D.country
ORDER BY
number_of_customers DESC
LIMIT 10
But I would like to use a subquery rather than listing the countries which I found using a previous query:
SELECT
COUNT(A.customer_id) AS number_of_customers,
D.country
FROM
customer A
INNER JOIN
address B ON A.address_id = B.address_id
INNER JOIN
city C ON B.city_id = C.city_id
INNER JOIN
country D ON C.country_ID = D.country_ID
GROUP BY
D.country
ORDER BY
number_of_customers DESC
LIMIT 10
How can I combine these two queries correctly? I keep getting different errors when I try to replace the list of countries with in the second query I posted. I apologize if this is a stupid question; I am a beginner.
My attempt:
SELECT
COUNT(A.customer_id) AS number_of_customers,
D.country, C.city
FROM
customer A
INNER JOIN
address B ON A.address_id = B.address_id
INNER JOIN
city C ON B.city_id = C.city_id
INNER JOIN
country D ON C.country_ID = D.country_ID
WHERE
country IN (SELECT COUNT(A.customer_id) AS number_of_customers, D.country
FROM customer A
INNER JOIN address B ON A.address_id = B.address_id
INNER JOIN city C ON B.city_id = C.city_id
INNER JOIN country D ON C.country_ID = D.country_ID
GROUP BY D.country
ORDER BY number_of_customers DESC
LIMIT 10)
GROUP BY
C.city, D.country
ORDER BY
number_of_customers DESC
LIMIT 10
But I get an error
subquery has too many columns
For instance, in PostgreSQL you can use with queries, see the Documentation:
WITH top_countries AS (
SELECT count(A.customer_id) AS number_of_customers,
D.country AS country
FROM customer A
INNER JOIN address B ON A.address_id = B.address_id
INNER JOIN city C ON B.city_id = C.city_id
INNER JOIN country D ON C.country_ID = D.country_ID
GROUP BY D.country
ORDER BY number_of_customers DESC
LIMIT 10
)
SELECT count(A.customer_id) AS number_of_customers,
D.country, C.city
FROM customer A
INNER JOIN address B ON A.address_id = B.address_id
INNER JOIN city C ON B.city_id = C.city_id
INNER JOIN country D ON C.country_ID = D.country_ID
WHERE country IN (SELECT tc.country FROM top_countries)
GROUP BY C.city,D.country
ORDER BY number_of_customers DESC
LIMIT 10
Related
I need to get clarified the below situation.
I have a city, country table and I need to validate this will some other tables and get the city country results ordered by the country. Here's my query for that
SELECT distinct
c.code as CITY ,
c.country as COUNTRY from location_info li
inner join someTable s on li.loc_id = s.some_id
inner join city c on s.city = c.code
ORDER BY c.country
And this provides the results as
Now when I use OFFSET and LIMIT values in the below query
SELECT distinct
c.code as CITY,
c.country as COUNTRY from location_info li
inner join someTable s on li.loc_id = s.some_id
inner join city c on s.city = c.code
ORDER BY c.country OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY.
I expect to get ADOR, ADPC, ADSJ, ADVD, ALV as the output.
Why is that and what I am missing here in this query.
When I do the following I get the expected outcome
SELECT CITY, COUNTRY FROM ( SELECT distinct
c.code as CITY,
c.country as COUNTRY from location_info li
inner join someTable s on li.loc_id = s.some_id
inner join city c on s.city = c.code
ORDER BY c.country ) OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY.
The issue is that the ORDER BY is not stable. What that means is that you have ties in the key values. So, running the query two times might result in different orderings.
This is easily fixed by including more keys in the order by so the order by keys uniquely identify each row:
select distinct c.code as CITY, c.country as COUNTRY
from location_info li join
someTable s
on li.loc_id = s.some_id join
city c
on s.city = c.code
order by c.country, c.code;
I have been trying to query each city's popular genre. I am only trying to get the rows that I have highlighted. I tried using MAX() on a group by but gave me a syntax error.
My CTE query is as follows, its based on the dbeaver sample dataset:
with q_table
as
( select City, Genre, count(*) as counts
from
(select c.City, g.Name as Genre
from bus5dwr.dbeaver_sample.Customer c
inner join bus5dwr.dbeaver_sample.Invoice i
on i.CustomerId = c.CustomerId
inner join bus5dwr.dbeaver_sample.InvoiceLine il
on il.InvoiceId = i.InvoiceId
inner join bus5dwr.dbeaver_sample.track t
on t.TrackId = il.TrackId
inner join bus5dwr.dbeaver_sample.Genre g
on g.GenreId = t.GenreId
where Country = 'USA'
) as t2
group by City, Genre)
I tried the following query.
I don't have a dataset to test this on, but you should be able to just add a ROW_NUMBER() function to your CTE to get the values you are looking for. Such as:
with q_table
as
( select City, Genre, count(*) as counts,
,ROW_NUMBER() OVER(partition by City order by count(*) desc) RN
from
(select c.City, g.Name as Genre
from bus5dwr.dbeaver_sample.Customer c
inner join bus5dwr.dbeaver_sample.Invoice i
on i.CustomerId = c.CustomerId
inner join bus5dwr.dbeaver_sample.InvoiceLine il
on il.InvoiceId = i.InvoiceId
inner join bus5dwr.dbeaver_sample.track t
on t.TrackId = il.TrackId
inner join bus5dwr.dbeaver_sample.Genre g
on g.GenreId = t.GenreId
where Country = 'USA'
) as t2
group by City, Genre)
SELECT City, Genre, Counts
from q_table
WHERE RN=1
Order BY City
This use of MAX should work.
Edit; Added inner join. Thanks to Gordon Linoff for the observation that my original answer didn't actually achieve anything.
with q_table
as
( select City, Genre, count(*) as counts
from
(select c.City, g.Name as Genre
from bus5dwr.dbeaver_sample.Customer c
inner join bus5dwr.dbeaver_sample.Invoice i
on i.CustomerId = c.CustomerId
inner join bus5dwr.dbeaver_sample.InvoiceLine il
on il.InvoiceId = i.InvoiceId
inner join bus5dwr.dbeaver_sample.track t
on t.TrackId = il.TrackId
inner join bus5dwr.dbeaver_sample.Genre g
on g.GenreId = t.GenreId
where Country = 'USA'
) as t2
group by City, Genre)
SELECT a.City, a.Genre, a.counts
FROM q_table a
INNER JOIN (
SELECT City, MAX(counts) counts
FROM q_table
GROUP BY City
) b ON a.City = b.City AND a.counts = b.counts;
try this
with q_table
as
(select * from (
( select City, Genre, count(*) as counts
from
(select c.City, g.Name as Genre
from bus5dwr.dbeaver_sample.Customer c
inner join bus5dwr.dbeaver_sample.Invoice i
on i.CustomerId = c.CustomerId
inner join bus5dwr.dbeaver_sample.InvoiceLine il
on il.InvoiceId = i.InvoiceId
inner join bus5dwr.dbeaver_sample.track t
on t.TrackId = il.TrackId
inner join bus5dwr.dbeaver_sample.Genre g
on g.GenreId = t.GenreId
where Country = 'USA'
) as t2
group by City, Genre)) as t3 where count in (select max(count) count from t3 group by city)
i have the following Query
USE Movies;
SELECT
c.CountryName
,d.DirectorName
,f.FilmRunTimeMinutes AS [TotalRunTime]
FROM
tblFilm as f
JOIN tblCountry as c on c.CountryID = f.FilmCountryID
JOIN tblDirector as d on d.DirectorID = f.FilmDirectorID
ORDER BY
DirectorName
which gives me the following result:
so far so good.
Then i grouped my result, to Sum up the TotalRunTime for each Director and Country:
SELECT
c.CountryName
,d.DirectorName
,SUM(CONVERT(DECIMAL, f.FilmRunTimeMinutes)) AS [TotalRunTime]
,COUNT(*)
FROM
tblFilm as f
JOIN tblCountry as c on c.CountryID = f.FilmCountryID
JOIN tblDirector as d on d.DirectorID = f.FilmDirectorID
GROUP BY
CountryName
,DirectorName
this gives me following result:
Now i want the actor with the highest Count(*) (the colum 'no column name') and i tried this:
SELECT
c.CountryName
,d.DirectorName
,SUM(CONVERT(DECIMAL, f.FilmRunTimeMinutes)) AS [TotalRunTime]
,COUNT(*)
FROM
tblFilm as f
JOIN tblCountry as c on c.CountryID = f.FilmCountryID
JOIN tblDirector as d on d.DirectorID = f.FilmDirectorID
GROUP BY
CountryName
,DirectorName
HAVING
COUNT(*) = MAX(Count(*))
But it´s not working :(. Can you please explain me why it´s not working in detail and how i can get the row with the max(count(*))? In this example it should give me the row Japan | Akira usw.
Just use TOP (1) clause :
SELECT TOP (1) c.CountryName, d.DirectorName,
SUM(CONVERT(DECIMAL, f.FilmRunTimeMinutes)) AS [TotalRunTime]
COUNT(*) AS cnt
FROM tblFilm as f JOIN
tblCountry as c
on c.CountryID = f.FilmCountryID JOIN
tblDirector as d
on d.DirectorID = f.FilmDirectorID
GROUP BY CountryName, DirectorName
ORDER BY cnt DESC;
However, this might be fail if the cnt has ties if so, then use RANK() instead :
SELECT t.*
FROM (SELECT c.CountryName, d.DirectorName,
SUM(CONVERT(DECIMAL, f.FilmRunTimeMinutes)) AS [TotalRunTime]
COUNT(*) AS cnt,
RANK() OVER (ORDER BY COUNT(*) DESC) AS Seq
FROM tblFilm as f JOIN
tblCountry as c
ON c.CountryID = f.FilmCountryID JOIN
tblDirector as d
ON d.DirectorID = f.FilmDirectorID
GROUP BY CountryName, DirectorName
) t
WHERE seq = 1;
I dont know who to return what I wrote before, apologise. vowejin firnefk rneqkln qrecjinrelqkjnr klwencirowejncienfvenciernicnreinc ikrenicernircniwncikwnkwjnkcjwnkjnckjncwkjnwckjnweknckejnckwjnckjnwekcjnwekjnckwjenckjwenkcjnwekjnckwenckwjenklwneocnwocnowencoejnkjwencojnwekojcnwekjcnkwejnckejcnkwejnckjwenkcjnwkjcnwkn:)
Using TOP:
SELECT TOP 1
PID, NAME, AGE
FROM (
SELECT
p.*, h.HID
FROM Performer p
INNER JOIN Concert c
ON c.PID = p.PID
INNER JOIN Hall h
ON h.HID = c.HID
INNER JOIN Tickets t
ON t.CID = c.CID
GROUP BY p.PID, p.NAME, p.AGE, h.HID, h.CAPACITY
HAVING COUNT(t.TID) = h.CAPACITY
) t
GROUP BY PID, NAME, AGE
ORDER BY COUNT(*) DESC
This should return expected result
;with Cte1 AS (
select C.CID, P.Name AS PerformerName, H.Name AS HallName, H.Capacity, H.HID
from #Performer P
inner join #Concert C on C.PID = P.PID
inner join #Hall H on H.HID = C.HID
)
, Cte2 AS (
select C.CID, H.HID, COUNT(*) SellCount
from #Concert C
inner join #Hall H on H.HID = C.HID
inner join #Tickets T on T.CID = C.CID
group by C.CID, H.HID
)
select Cte1.CID, Cte1.PerformerName, Cte1.HallName, Cte2.SellCount
from Cte1 inner join Cte2 on Cte2.CID = Cte1.CID AND Cte2.HID = Cte1.HID
where Cte1.Capacity = Cte2.SellCount
I find database records which are duplicated like so :
select s.name, r.name Region, c.name Country
from supplier s
join region r on r.id = s.regionid
join region c on c.id = isnull(r.pid, r.id)
group by s.name, r.name, c.name
having count(s.name) >1
whats the best way to list them all (so if two duplicates it will appear twice etc...)
The easiest way is to create an in-line query from your Find-dups query and join to a "without-a-group-by" query.
select s.name, r.name Region, c.name Country
from supplier s
join region r on r.id = s.regionid
join region c on c.id = isnull(r.pid, r.id)
inner join (select s.name, r.name Region, c.name Country
from supplier s
join region r on r.id = s.regionid
join region c on c.id = isnull(r.pid, r.id)
group by s.name, r.name, c.name
having count(s.name) >1 ) dups
ON s.name = dups.name
and r.name = dups.region
and c.name = dups.country
I think this should do it:
with C as (
select
s.name,
r.name Region,
c.name Country,
count(*) over (
partition by s.name, r.name, c.name
) as ct
from supplier s
join region r on r.id = s.regionid
join region c on c.id = isnull(r.pid, r.id)
)
select
name, Region, Country
from C
where ct > 1;