How to select a max row for each group in SQL - sql

I want select countries with maximum value of 'Value' for a 'grpid'. Also already selected 'Country' should not be considered for other 'grpid' while checking the maximum. ( ie Country or grpid should not be repeated in the result )
SQL Fiddle
Result:
Country grpid Value Row_number
US 49707 604456458 1
GB 5086 497654945 4
CA 909 353500201 10
JP 231 198291290 15

try this query instead,
WITH OrderedOrders AS
(
SELECT country,grpid,value,ROW_NUMBER() OVER(PARTITION BY country ORDER BY country,value DESC) AS 'RowNumber'
FROM test1
)
select * from OrderedOrders
where RowNumber =1

I believe this is what you're looking for:
SQL Fiddle
;with cte as
(
select
country,
max(value) as MaxVal,
min(row_number) as MinRow
from test1
group by Country
)
select
c.country,
t.grpid,
c.MaxVal,
c.MinRow
from cte c
join test1 t
on t.country = c.country
and t.value = c.MaxVal
and t.row_number = c.MinRow
order by country, grpid

Can you please try out this query
select
country,
value,
grpid,
count(*)
from test1
group by
country,
value,
grpid
order by
country,
value desc

Related

select value based on max of other column

I have a few questions about a table I'm trying to make in Postgres.
The following table is my input:
id
area
count
function
1
100
20
living
1
200
30
industry
2
400
10
living
2
400
10
industry
2
400
20
education
3
150
1
industry
3
150
1
education
I want to group by id and get the dominant function based on max area. With summing up the rows for area and count. When area is equal it should be based on max count, when area and count is equal it should be based on prior function (i still have to decide if education is prior to industry or vice versa). So the result should be:
id
area
count
function
1
300
50
industry
2
1200
40
education
3
300
2
industry
I tried a lot of things and maybe it's easy, but i don't get it. Can someone help to get the right SQL?
One method uses row_number() and conditional aggregation:
select id, sum(area), sum(count),
max(function) over (filter where seqnum = 1) as function
from (select t.*,
row_number() over (partition by id order by area desc) as seqnum
from t
) t
group by id;
Another method uses ``distinct on`:
select id, sum(area) over (partition by id) as area,
sum(count) over (partition by id) as count,
function
from t
order by id, area desc;
Use a scalar sub-query for "function".
select t.id, sum(t.area), sum(t.count),
(
select "function"
from the_table
where id = t.id
order by area desc, count desc, "function" desc
limit 1
) as "function"
from the_table as t
group by t.id order by t.id;
SQL Fiddle
you can use sum as window function:
select distinct on (t.id)
id,
sum(area) over (partition by id) as area,
sum(count) over (partition by id) as count,
( select function from tbl_test where tbl_test.id = t.id order by count desc limit 1 ) as function
from tbl_test t
This is how you get the function for each group based on id:
select id, function
from yourtable yt1
left join yourtable yt2
on yt1.id = yt2.id and yt1.area < yt2.area
where yt2.area.id is null;
(we ensure that no yt2 exists that would be of the same id but of higher areay)
This would work nicely, but you might have several max areas with different values. To cope with this isue, let's ensure that exactly one is chosen:
select id, max(function) as function
from yourtable yt1
left join yourtable yt2
on yt1.id = yt2.id and yt1.area < yt2.area
where yt2.area.id is null
group by id;
Now, let's join this to our main table;
select yourtable.id, sum(yourtable.area), sum(yourtable.count), t.function
from yourtable
join (
select id, max(function) as function
from yourtable yt1
left join yourtable yt2
on yt1.id = yt2.id and yt1.area < yt2.area
where yt2.area.id is null
group by id
) t
on yourtable.id = t.id
group by yourtable.id;

SQL Server 2008 merging the result of two queries

I am trying to merge the result of both the queries below using the UNION operator in SQL Server 2008 but got the following error
Incorrect syntax near the keyword 'union'.
My code:
SELECT TOP 1
CITY, LEN(CITY)
FROM
table1
ORDER BY
LEN (CITY), CITY ASC
UNION
SELECT TOP 1
CITY, LEN(CITY)
FROM
table1
ORDER BY
LEN (CITY) DESC, CITY ASC
Any comments would be appreciated.
Thanks
Here is the correct way to do it
Select * From
(
SELECT TOP 1
CITY, cityLen = LEN(CITY)
FROM
table1
ORDER BY
cityLen, CITY ASC
) a
UNION
Select * From
(
SELECT TOP 1
CITY, cityLen = LEN(CITY)
FROM
table1
ORDER BY
cityLen DESC, CITY ASC
) b
or using Row_Number window function
select * from
(
select *,
ROW_NUMBER() OVER(ORDER BY LEN (CITY) DESC, CITY ASC) as Drn,
ROW_NUMBER() OVER(ORDER BY LEN (CITY) ASC, CITY ASC) as Arn,
FROM table1
) a
where 1 in (Arn,Drn)
In this case, you can use Common table expression. Try this
;With cte
AS (
select * , ROW_NUMBER() OVER(ORDER BY LEN (CITY) DESC, CITY ASC) as rn
FROM table1
)
select * from cte where rn = 1
union
select * from cte where rn = 1
Remove the ASC order command in your first select statement. You can only order the result at the end of any query as ordering in the middle of a query (if allowed) would cause many problems in getting consistent results.
EDIT: I realized the table were the same, you need to use Union ALL, or as stated in other comments, the duplicates are taken out in a UNION.
SELECT TOP 1
CITY, LEN(CITY)
FROM
table1
UNION ALL
SELECT TOP 1
CITY, LEN(CITY)
FROM
table1
ORDER BY
LEN (CITY) DESC, CITY ASC

Aggregation of unique rows in SQL

I have the following table of unique rows:
Name change Number_of_Sales
Soby 2.22 8370
Sollerod -1.06 11287
Sonderborg 2.60 6343
Sonderhald 11.43 1623
Sonderhald 10.93 2098
I want to select name and change, excluding duplicate Names, so that Sonderhald only occurs once. I want the Sonderhald with the maximum Number_of_Sales.
How can I do this in SQL Server?
Thanks
SELECT t.name, t.change, t.number_of_sales
FROM your_table t
INNER JOIN (
SELECT tt.name, MAX(tt.number_of_sales) AS max_number_of_sales
FROM your_table tt
GROUP BY tt.name
) tm ON t.name = tm.name AND t.number_of_sales = tm.max_number_of_sales
You can use a common table expression to do this:
;
WITH cte
AS ( SELECT Name,
Change,
Number_of_Sales,
ROW_NUMBER() OVER ( PARTITION BY name ORDER BY number_of_sales DESC ) AS RowNum
FROM your_table
)
SELECT Name,
Change,
Number_of_Sales
FROM cte
WHERE RowNum = 1
http://technet.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx

sql query to find the duplicate records

what is the sql query to find the duplicate records and display in descending, based on the highest count and the id display the records.
for example:
getting the count can be done with
select title, count(title) as cnt from kmovies group by title order by cnt desc
and the result will be like
title cnt
ravi 10
prabhu 9
srinu 6
now what is the query to get the result like below:
ravi
ravi
ravi
...10 times
prabhu
prabhu..9 times
srinu
srinu...6 times
If your RDBMS supports the OVER clause...
SELECT
title
FROM
(
select
title, count(*) OVER (PARTITION BY title) as cnt
from
kmovies
) T
ORDER BY
cnt DESC
You can do it in a single query:
Select t.Id, t.title, z.dupCount
From yourtable T
Join
(select title, Count (*) dupCount
from yourtable
group By title
Having Count(*) > 1) z
On z.title = t.Title
order By dupCount Desc
This query uses the Group By and and Having clauses to allow you to select (locate and list out) for each duplicate record. The As clause is a convenience to refer to Quantity in the select and Order By clauses, but is not really part of getting you the duplicate rows.
Select
Title,
Count( Title ) As [Quantity]
From
Training
Group By
Title
Having
Count( Title ) > 1
Order By
Quantity desc
select distinct title, (
select count(title)
from kmovies as sub
where sub.title=kmovies.title) as cnt
from kmovies
group by title
order by cnt desc
You can't do it as a simple single query, but this would do:
select title
from kmovies
where title in (
select title
from kmovies
group by title
order by cnt desc
having count(title) > 1
)

how to calculate count in sql?

I have the following table:
memberid
2
2
3
4
3
...and I want the following result:
memberid count
2 2
3 1 ---Edit by gbn: do you mean 2?
4 1
I was attempting to use:
SELECT MemberID,
COUNT(MemberID)
FROM YourTable
GROUP BY MemberID
...but now I want find which record which has maximum count. IE:
memberid count
2 2
SELECT memberid, COUNT(*) FROM TheTable GROUP BY memberid
Although, it won't work for your desired output because you have "memberid = 3" twice.
Edit: After late update to question...
SELECT TOP 1 WITH TIES --WITH TIES will pick up "joint top".
memberid, COUNT(*)
FROM
TheTable
GROUP BY
memberid
ORDER BY
COUNT(*) DESC
SELECT MemberID, COUNT(MemberID) FROM YourTable GROUP BY MemberID
What if there is a tie (or more) for the max? Do you want to display one or all?
This is how I would do this
SELECT memberid, COUNT(1)
FROM members
GROUP BY memberid
HAVING COUNT(1) = (
SELECT MAX(result.mem_count)
FROM (
SELECT memberid, COUNT(1) as mem_count
FROM members
GROUP BY memberid
) as result
)
I would love to see a more efficient approach though.
Do it like this:
SELECT memberid, COUNT(memberid) AS [count] FROM [Table] GROUP BY memberid
This should do the trick with no subselects required:
select top 1 memberid, COUNT(*) as counted
from members
group by memberid
order by counted desc
Can be done quite easy:
SELECT TOP 1 MemberId, COUNT(*) FROM YourTable GROUP BY MemberId ORDER By 2 DESC
I believe the original poster requested 2 result sets.
The only way I know of to get this (in SQL Server) is to dump the original records into a temp table and then do a SELECT and MAX on that. I do welcome an answer that requires less code!
-- Select records into a temp table
SELECT
Table1.MemberId
,CNT = COUNT(*)
INTO #Temp
FROM YourTable AS Table1
GROUP BY Table1.MemberId
ORDER BY Table1.MemberId
-- Get original records
SELECT * FROM #Temp
-- Get max. count record(s)
SELECT
Table1.MemberId
,Table1.CNT
FROM #Temp AS Table1
INNER JOIN (
SELECT CNT = MAX(CNT)
FROM #Temp
) AS Table2 ON Table2.CNT = Table1.CNT
-- Cleanup
DROP TABLE #Temp
How about this query:
SELECT TOP 1 MemberID,
COUNT(MemberID)
FROM YourTable
GROUP BY MemberID
ORDER by count(MemberID) desc
SELECT count(column_name)
FROM your_table;
You need to use a subselect:
SELECT MemberID, MAX(Count) FROM
(SELECT MemberID, COUNT(MemberID) Count FROM YourTable GROUP BY MemberID)
GROUP BY MemberID
The second group by is needed to return both, the count and the MemberID.