Extract state with maximum count from subquery - sql

Select a.states,MAX(a.cnt) from
(Select ci_location.state as states,Count(CI_Location.State) Cnt from
Fact_Transactions ft
Inner join CI_Location on ft.ID_Location = CI_Location.ID_Location
Where id_model like 'smsg%'
Group by State)a
Group by a.states,a.Cnt
Output:-
State Count
Alabama 7
Arizona 15
Arkansas 4
California 100
Colorado 7
Required output:-
state output
California 100
This code isn't extracting STATE with maximum count value from my table...Is something wrong??

Try the following
SELECT TOP 1 -- or TOP 1 WITH TIES
ci_location.state as states,
Count(CI_Location.State) Cnt
FROM Fact_Transactions ft
INNER JOIN CI_Location ON ft.ID_Location = CI_Location.ID_Location
WHERE id_model like 'smsg%'
GROUP BY ci_location.state
ORDER BY Cnt DESC

just remove the a.cnt from group by
select a.states,MAX(a.cnt) from
(Select ci_location.state as states,Count(CI_Location.State) Cnt from
Fact_Transactions ft
Inner join CI_Location on ft.ID_Location = CI_Location.ID_Location
Where id_model like 'smsg%'
Group by State)a
Group by a.states

You should use row_number() function approach to get the maximum count state
SELECT * FROM
(
SELECT
l.state as states,
Count(l.State) as Cnt,
row_number() over (order by Count(l.State) desc) Sq
FROM Fact_Transactions ft
INNER JOJN CI_Location l on ft.ID_Location = l.ID_Location
WHERE l.id_model like 'smsg%'
GROUP BY l.State
) a
WHERE sq = 1
Note : For your current query you are further grouping the derived table result. Try, to remove GROUP BY clause & just use max() to get the highest count state only.

Related

Selecting rows with the most repeated values at specific column

Problem in general words: I need to select value from one table referenced to the most repeated values in another table.
Tables have this structure:
screenshot
screenshot2
The question is to find country which has the most results from sportsmen related to it.
First, INNER JOIN tables to have relation between result and country
SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id);
Then, I count how much time each country appear
SELECT country, COUNT(country) AS highest_participation
FROM (SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id))
GROUP BY country
;
And got this screenshot3
Now it feels like I'm one step away from solution ))
I guess it's possible with one more SELECT FROM (SELECT ...) and MAX() but I can't wrap it up?
ps:
I did it with doubling the query like this but I feel like it's so inefficient if there are millions of rows.
SELECT country
FROM (SELECT country, COUNT(country) AS highest_participation
FROM (SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id)
) GROUP BY country
)
WHERE highest_participation = (SELECT MAX(highest_participation)
FROM (SELECT country, COUNT(country) AS highest_participation
FROM (SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id)
) GROUP BY country
))
Also I did it with a view
CREATE VIEW temp AS
SELECT country as country_with_most_participations, COUNT(country) as country_participate_in_#_comp
FROM(
SELECT country, competition_id FROM result
INNER JOIN sportsman USING(sportsman_id)
)
GROUP BY country;
SELECT country_with_most_participations FROM temp
WHERE country_participate_in_#_comp = (SELECT MAX(country_participate_in_#_comp) FROM temp);
But not sure if it's easiest way.
If I understand this correctly you want to rank the countries per competition count and show the highest ranking country (or countries) with their count. I suggest you use RANK for the ranking.
select country, competition_count
from
(
select
s.country,
count(*) as competition_count,
rank() over (order by count(*) desc) as rn
from sportsman s
inner join result r using (sportsman_id)
group by s.country
) ranked_by_count
where rn = 1
order by country;
If the order of the result rows doesn't matter, you can shorten this to:
select s.country, count(*) as competition_count
from sportsman s
inner join result r using (sportsman_id)
group by s.country
order by count(*) desc
fetch first rows with ties;
You seem to be overcomplicating this. Starting from your existing join query, you can aggregate, order the results and keep the top row(s) only.
select s.country, count(*) cnt
from sportsman s
inner join result r using (sportsman_id)
group by s.country
order by cnt desc
fetch first 1 row with ties
Note that this allows top ties, if any.
SELECT country
FROM (SELECT country, COUNT(country) AS highest_participation
FROM (SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id)
) GROUP BY country
order by 2 desc
)
where rownum=1

Return only the highest-valued row

I'm trying to find a solution to only returns the highest-valued row from a SQL query
I have a query that joins two tables together and then checks how many times the id matches within the different tables (within 'athelete' the id param is unique).
SELECT t.athlete_id, count(a.id) as 'Number of activities' FROM training_session t
INNER JOIN athlete a ON t.athlete_id = a.id
WHERE t.athlete_id = a.id
GROUP BY a.id
The following table is returned
athlete_id Number of activities
1 4
2 1
3 1
4 1
5 1
6 1
The issued problem is that I only want to return the row with the highest number of activities. According to the table above this should be
athlete_id = 1 since it has the greatest amount of activities.
I would appreciate some pointers on how I could improve my query to match these queries.
Use ORDER BY and LIMIT:
SELECT t.athlete_id, count(*) as `Number of activities`
FROM training_session t INNER JOIN
athlete a
ON t.athlete_id = a.id
GROUP BY t.athlete_id
ORDER BY COUNT(*) DESC
LIMIT 1;
I don't think a JOIN is needed for this query:
SELECT t.athlete_id, COUNT(*) as `Number of activities`
FROM training_session t
GROUP BY t.athlete_id
ORDER BY COUNT(*) DESC
LIMIT 1;
And if you want all rows in the event of ties, then this requires a bit more work. I would recommend ranking functions:
SELECT *
FROM (SELECT t.athlete_id, COUNT(*) as `Number of activities`,
RANK() OVER (ORDER BY COUNT(*) DESC) as seqnum
FROM training_session t
GROUP BY t.athlete_id
) t
WHERE seqnum = 1;

Top 10 by Customer - Total

I'm having some issues....how do I get the following code fixed to return the table below as a sum of customers? I want a total of customer quantities by customer, and then a top 10 list. So all of the Yellow Rose should be added together and then counted as one entry, instead of all of their shipments showing up individually.
select top 10 T1.Quantity, T1.CustName
from
(
select
SUM(Tkscale.Qty)Quantity,
Slcust.Name CustName
from Tkscale with (nolock)
left outer join Slcust with (nolock) on Tkscale.CustomerID = Slcust.CustomerID
group by Tkscale.CustomerID, Tkscale.Qty, Slcust.Name
) T1
order by T1.CustName desc, T1.Quantity desc
try to remove in grouping 'Tkscale.Qty'
Remove the Tkscale.Qty from the GROUP BY clause in your inner query. I also think that you want top 10 largest customers by quantity, not by their names:
select top 10 T1.Quantity, T1.CustName
from
(
select
SUM(Tkscale.Qty)Quantity,
Slcust.Name CustName
from Tkscale with (nolock)
left outer join Slcust with (nolock) on Tkscale.CustomerID = Slcust.CustomerID
group by Slcust.Name
) T1
order by T1.Quantity desc, T1.CustName desc
^ change the sequence of the ORDER BY clause

Count and result from Inner Join

I have this query
SELECT COUNT(*) FROM (
SELECT
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR,
Count(*) AS counts
FROM
ARTIKEL ART
INNER JOIN ARTSTLST ON ARTSTLST.OARTIKELLFDNR = ART.LFDNR
WHERE
ART.SUCHARTIKELNR = '22424'
GROUP BY
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR )
which results in my case in
3
But I want to show also the result of the inner query
SELECT
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR,
Count(*) AS counts
FROM
ARTIKEL ART
INNER JOIN ARTSTLST ON ARTSTLST.OARTIKELLFDNR = ART.LFDNR
WHERE
ART.SUCHARTIKELNR = '22424'
GROUP BY
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR
so the result would look like this
12345 34567 3
Which is the result of the selct plus the Count() result.
This would be easy using Windowed Aggregate Function:
SELECT
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR,
Count(*) AS counts,
SUM(Count(*)) OVER () -- Group sum
FROM
ARTIKEL ART
INNER JOIN ARTSTLST ON ARTSTLST.OARTIKELLFDNR = ART.LFDNR
WHERE
ART.SUCHARTIKELNR = '22424'
GROUP BY
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR
But AFAIK only Firebird 3 (currently in beta) supports those functions, so you need a more complicated query utilizing a Common Table Expression:
WITH cte AS
(
SELECT
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR,
Count(*) AS counts
FROM
ARTIKEL ART
INNER JOIN ARTSTLST ON ARTSTLST.OARTIKELLFDNR = ART.LFDNR
WHERE
ART.SUCHARTIKELNR = '22424'
GROUP BY
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR
)
SELECT cte.*, (SELECT SUM(counts) FROM cte)
FROM cte

Highest Count with a group

I'm having an absolute brain fade
SELECT p.ProductCategory, f.ProductSubCategory, COUNT(*) AS Cnt
FROM Sales f
JOIN Products p ON f.ProductSubCategory = p.ProductSubCategory
GROUP BY p.ProductCategory, f.ProductSubCategory
ORDER BY 1,3 DESC
This shows me the count for each ProductSubCategory, I would like to see only the highest ProductSubCategory per ProductCategory.
I wish to see (I don't care about the Count value)
There are a couple of different ways to do this. One involves joining the results back to themselves and using the max aggregate. But since you are using SQL Server, you can use ROW_NUMBER to achieve the same result:
with cte as (
select p.productcategory, p.ProductSubCategory, COUNT(*) cnt,
ROW_NUMBER() over (partition by p.productcategory order by count(*) desc) rn
from products p
join sales s on p.ProductSubCategory = s.ProductSubCategory
group by p.productcategory, p.ProductSubCategory
)
select *
from cte
where rn = 1
You already got the answer, Please see the following code to. It may help you.
SELECT p.ProductCategory,
f.ProductSubCategory,
COUNT(*) AS Cnt
FROM Sales f
JOIN Products p ON f.ProductSubCategory = p.ProductSubCategory
JOIN (
SELECT p.ProductCategory,
f.ProductSubCategory,
ROW_NUMBER() OVER ( PARTITION BY p.ProductCategory,
f.ProductSubCategory
ORDER BY COUNT(*) DESC) [Row]
FROM Sales f
JOIN Products p ON f.ProductSubCategory = p.ProductSubCategory) Lu
ON P.ProductCategory = Lu.ProductCategory
AND f.ProductSubCategory = Lu.ProductSubCategory
WHERE Lu.Row = 1
GROUP By p.ProductCategory,
f.ProductSubCategory