get a distinct row along with it values - sql

so i wanted to get the expected result, while using a sub query but my answer isnt going to plan, below is the code i have and the result alongside my expected result
SELECT "Invoice"."BillingCountry", "Genre"."Name", COUNT("Track"."TrackId") FROM "Track"
INNER JOIN "Genre"
ON "Track"."GenreId" = "Genre"."GenreId"
INNER JOIN "InvoiceLine"
ON "Track"."TrackId" = "InvoiceLine"."TrackId"
INNER JOIN "Invoice"
ON "InvoiceLine"."InvoiceId" = "Invoice"."InvoiceId"
WHERE "Invoice"."BillingCountry" in ('USA', 'Canada', 'Brazil', 'france', 'Germany')
GROUP BY "Genre"."GenreId", "Invoice"."BillingCountry"
ORDER BY COUNT("Track"."TrackId") DESC
LIMIT 10
billingcountry | name | count
usa bat 50
canada bat 43
usa car 40
usa toy 39
germany bat 36
france bat 34
canada bike 20
usa fing 15
brazil bat 14
france shoe 10
expected result
country | item | count
usa bat 50
canada bat 43
germany bat 36
france bat 34
brazil bat 14
i know there are similar solutions here, but i cant just get them to work, will be grateful if someone can help

You seem to want the most popular genre per country. If so, use DISTINCT ON:
SELECT DISTINCT ON (i."BillingCountry") i."BillingCountry", g."Name", COUNT(*)
FROM "Track" t JOIN
"Genre" g
ON t."GenreId" = g."GenreId" JOIN
"InvoiceLine" il
ON t."TrackId" = il."TrackId" JOIN
"Invoice" i
ON il."InvoiceId" = i."InvoiceId"
WHERE i."BillingCountry" in ('USA', 'Canada', 'Brazil', 'France', 'Germany')
GROUP BY g."GenreId", i."BillingCountry"
ORDER BY i."BillingCountry", COUNT(*) DESC ;
Note how table aliases make the query easier to write and read. I would also fix the table definitions so you don't have to escape table and column names -- having to escape them is a really, really bad practice.

You can use sub query and max as follows:
Select "BillingCountry", "Name", max(cnt) as sm_result from
(SELECT "Invoice"."BillingCountry", "Genre"."Name",
COUNT("Track"."TrackId") FROM "Track" as cnt
INNER JOIN "Genre"
ON "Track"."GenreId" = "Genre"."GenreId"
INNER JOIN "InvoiceLine"
ON "Track"."TrackId" = "InvoiceLine"."TrackId"
INNER JOIN "Invoice"
ON "InvoiceLine"."InvoiceId" = "Invoice"."InvoiceId"
WHERE "Invoice"."BillingCountry" in ('USA', 'Canada', 'Brazil', 'france', 'Germany')
GROUP BY "Genre"."GenreId", "Invoice"."BillingCountry"
ORDER BY COUNT("Track"."TrackId") DESC
LIMIT 10) t
Group by "BillingCountry", "Name"

Related

How can I write SQL Query?

I need a request that displays the name and surname of the clients with the smallest credit limit - among married women who do not live in Japan, Brazil or Italy.
Diagram:
This will Give all the people not in 'Japan', 'Brazil' or 'Italy') ,
Select C.Cust_first_name,C.Cust_Last_name from Customers C
Inner Join Countries C1
on C.Country_Id=C1.Country_Id
Where C1.Country_Name Not in('Japan', 'Brazil' or 'Italy')
and
C.Cust_Credit_Limit=(Select Min(Cust_Credit_Limit) From from Customers C)
If we Convert The Question to Code that will be the above code,
The Script would return the name and last name of person not in ('Japan', 'Brazil' or 'Italy') And has the lowest salary In the entire customer Base.
select top 1 * from Customers C
Inner Join
(
select MIn(cust_credit_limit) from Customers C1
Inner Join Countries CT on C1.Country_id = C1.Country_id
where CT.Country_Name Not in ('Japan', 'Brazil','Italy')
)
C2 on C2.cust_credit_limit = C.cust_credit_limit

SQL Query with different aggregation for count

Publisher
pub_id title_id city
1 1 NY
1 2 NY
2 3 CA
3 4 VA
Titles
title_id price genre
1 10 Horror
2 5 Bio
3 50 Science
Question:
Create a SQL query that gives
-pub_id
-# titles
-# titles with Horror genre
I have been having hard time writing this SQL query and can't figure out how to include both #titles and #titles with horror genre in the same query. I would appreciate any help on this. Thank you.
Query I have tried so far( don't know how to incude titles with horror genre):
select a.pub_id, count(a.titles)
from publisher a
left join titles b on a.title_id = b.title_id group by a.pub_id
If I use having then I won't be able to calculate the total number of titles.
use following query to achieve your results
select
pub_id,
count(*) as [titles],
SUM(CASE WHEN genre='horror' then 1 else 0 END) as [horror titles]
from Publisher a
inner join titles b on a.title_id=b.title_id
group by
pub_id
you can use CASE statements to do this
you can use this query to get expected output
select t.pub_id, COUNT(t.title_id) as title_id, t2.genre
from table1 t
inner join
table2 t2
on t.title_id = t2.title_id and t2.genre like 'Horror%'
group by t.pub_id, t2.genre
Note: change table1 and table2 names into your table name
the output is shown here

How to use all records from another table as counting columns?

I have 4 tables:
location:
location_id name
------------------------
1 France
device:
device_id location_id model_id
-------------------------------------
1 1 1
2 1 2
3 1 3
model:
model_id family_id name
-------------------------------------
1 1 C-max
2 1 S-max
3 2 Vectra
and family:
family_id name
---------------------
1 Ford
2 Opel
I need to build a complicated SQL query now. As the result, I would like to receive this:
location_id name Ford Opel
------------------------------------------
1 France 2 1
Is it possible to do it in SQL at all? I see there there problems:
About using other table records as columns in the query
About nested tables
About counting the elements (count function?)
Any comments/reference materials will be for me helpful. I do not await the final code.
In SQL queries the columns are fix. You get more or less rows depending on data, not columns. But that doesn't matter, because SQL is about to get data not to display it. The latter is a task for the GUI layer.
So get the desired data, which is the number of models per location and family mainly.
select l.location_id, l.name as location_name, f.name as family_name, count(*) as models
from location l
join device d on d.location_id = l.location_id
join model m on m.model_id = d.model_id
join family f on f.family_id = m.family_id
group by l.location_id, l.name, f.name
order by l.location_id, l.name, f.name;
This is all you need from the database. How to show the data is a task for your programm, a Delphi app in your case. So use Delphi to read the data with above query and fill your grid in a simple loop.
Thank you all for your helpful tips.
I solved my problem using the static method and the code published by #Matt. Because somebody else may looking for the solution, I paste here my working query for PostgreSQL:
SELECT DISTINCT t.location_id, t.name, SUM(t.ford) AS ford, SUM(t.opel) as opel
FROM(
SELECT l.location_id, l.name,
(SELECT COUNT(m.family_id) WHERE m.family_id = '1') AS ford,
(SELECT COUNT(m.family_id) WHERE m.family_id = '2') AS opel
FROM location l
INNER JOIN device d ON l.location_id = d.location_id
INNER JOIN model m ON d.model_id = m.model_id
INNER JOIN family f ON m.family_id = f.family_id
GROUP BY l.location_id, l.name, m.family_id
) t
GROUP BY t.location_id;

Inner Join from group by

I have a table countries containing country codes and names:
name code
FRANCE FR
JAPAN JP
And a table of page view stats views:
page_id code date etc...
34 FR 2015-01-01
34 FR 2015-01-02
34 JP 2015-01-02
I'd like to output a list of all the countries that the page was seen in, but with the country name, so the results should say: FRANCE, JAPAN
I can easily get the list of country codes that it runs in:
SELECT code FROM views WHERE page_id = 34 GROUP BY code;
But mapping them across to the names in the countries table is the hard bit. Any ideas?
I've tried this, but it doesn't work:
SELECT
countries.name as name_from_countries,
FROM
countries
INNER JOIN name_from_countries ON countries.code = views.code
WHERE
views.page_id = 34
GROUP BY
views.code
You don't need GROUP BY here. Just use DISTINCT.
SELECT DISTINCT countries.name as name_from_countries
FROM countries
INNER JOIN views ON countries.code = views.code
WHERE
views.page_id = 34
You need to add countries.name to your GROUP BY - I'm assuming you have some aggregates here:
SELECT v.code, c.name AS name_from_countries
FROM views v INNER JOIN countries c
ON v.code = c.code
WHERE v.page_id = 34
GROUP BY v.code, c.name;
If you don't have any aggregates (e.g., COUNT(*)), then you can get a list of countries with at least one view as follows:
SELECT c.code, c.name AS name_from_countries
FROM countries c
WHERE EXISTS ( SELECT 1 FROM views v
WHERE v.code = c.code
AND v.page_id = 34 );

How do I fetch the count from MS Access tables using group by clause?

I'm having an absolute brain breakdown with this SQL query, I'm hoping someone can shine some light with what I should be doing.
I have the following tables and they are linked by "anumber";
athletes
--------
anumber (id)
acountry ('Australia','Japan')
aname
result_placing
--------------
result_id id
anumber (id linked to athletes)
result_placing (Gold, Silver or null)
I would like to get a list of countries with how many gold, silver results associated. so output like:
country | resul_placing | result_count
----------- | ------------- | ------------
Australia | Gold | 2
Australia | Silver | 1
I tried something like this:
SELECT acountry
FROM athletes
INNER JOIN result_placing
ON athletes.anumber = result_placing.anumber
Which shows
Australia | Gold |
Australia | Silver |
Just not sure how to get the count of each. I tried count(distinct) but Access doesn't like it.
As soon as I use Count in it like:
SELECT a.acountry
, r.placing
, count(a.acountry)
FROM athlete a
INNER JOIN result_place r
ON a.anumber = r.anumber
I receive:
You tried to execute a query that does not include the specified expression 'acountry' as part of an aggregate function
Try
SELECT a.acountry
, r.result_placing
, sum(*) as cnt
FROM athletes a
RIGHT JOIN result_placing r
ON a.anumber = r.anumber
GROUP BY a.acountry
, r.result_placing
ORDER BY a.acountry
Haven't tried this out, but here goes. You need to use group by. Please try the following query
SELECT a.acountry, r.result_placing, count(a.acountry) FROM athletes a INNER JOIN result_placing r ON a.anumber = r.anumber group by a.acountry, r.result_placing
Here is one way to query the data using LEFT OUTER JOIN and GROUP BY.
Script:
SELECT a.acountry
, IIf(r.result_placing = ''
OR IsNull(r.result_placing),
'n/a',
r.result_placing
) AS medal
, COUNT(r.result_id) AS medalcount
FROM athletes a
LEFT OUTER JOIN result_placing r
ON a.anumber = r.anumber
GROUP BY a.acountry
, r.result_placing
Table Data:
athletes table data
results_placing table data
Output:
Query output