Problem with top 10 rows in a sql query? - sql

As a beginner in Sql Server 2005, i should get some help in getting top 10 from a table.
The scenario is like, a table Invitecount has multiple records for each userid. i have distinct userid's with the following sql query
Select distinct(userid) from inviteCount
For each userid, i get the number of points using the following query
Select sum(points) from invitecount
where UserID = 126429
And after i get the sum, i should have top 10 users with max points. My problem here is with writing all these statements together using arrays, etc.
IF someone could help me, i really appreciate it. Thanks in advance!

Try this:
SELECT TOP 10 userID, SUM(Points)
FROM inviteCount
GROUP BY UserId
ORDER BY SUM(Points) desc
I'm not sure what you mean by using arrays, but this would get you the top ten userIds ordered by the sum of points.

Try this:
Select TOP 10 userid, sum(points) from inviteCount group by userid order by sum(points) desc

You want something like:
select top 10
userid,
pointstotal = sum(points)
from
invitecount
group by userid
order by sum(points) desc
Note the order by.
A fancier version would be
select
userid
pointstotal = sum(points) over (partition by userid),
row_number = row_number() over (partition by userid order by sum(points) desc)
from
invitecount i
where
row_number <= 10
(untested - so probably needs a tweak)

Related

Show only the most frequest number SQL

How do i show only the highest value?
Even if there a tie
So like is there anyway to use MAX COUNT
using sqlLite
SELECT GAMEID,
COUNT(GAMEID)
FROM GAMES
GROUP BY GAMEID
ORDER BY COUNT(GAMEID) DESC
If you expect more than one row with the same count, you can use window functions to do this and deal with the ties.
You didn't specify your DBMS product, but the following is 100% ANSI standard SQL:
SELECT *
FROM (
SELECT gameid,
count(*),
dense_rank() over (order by count(*) desc) as rnk
FROM games
GROUP BY gameid
) t
WHERE rnk = 1
Online example
Since it sounds like you're using an outdated sqlite version and can't use window functions, here's another approach that handles ties:
WITH counted AS (SELECT gameid, count(gameid) AS count FROM games GROUP BY gameid)
SELECT gameid, count
FROM counted
WHERE count = (SELECT max(count) FROM counted);
You can add "LIMIT 1" to the end of the query and it will only show one result. However, if 2 entries have the same result it's arbitrary which one will be shown.
If you don't care about ties, then just use LIMIT:
SELECT GAMEID, COUNT(GAMEID) AS CNT
FROM GAMES
GROUP BY GAMEID
ORDER BY COUNT(GAMEID) DESC
LIMIT 1;
If you want to find the games having the highest count, including possible ties, then the RANK analytic function provides one option here:
WITH cte AS (
SELECT GAMEID, COUNT(GAMEID) AS CNT, RANK() OVER (ORDER BY COUNT(GAMEID) DESC) rnk
FROM GAMES
GROUP BY GAMEID
)
SELECT GAMEID, CNT
FROM cte
WHERE rnk = 1;

Optimize a query for creating a ranking in MS SQL Server

I'm creating an application where users do workouts. They pass on their results via an app, and these results are stored in an SQL Server database. Results are saved in this way in a SQL Server table:
I want to write a query to create a ranking based on the best score of each user. This is what I have so far:
SELECT id,
workout_id,
level_id,
a.user_id,
total_time,
score,
datetime_added
FROM nodefit_rankings_fitness as a INNER JOIN
(
SELECT user_id,
MAX(score) AS MAXSCORE
FROM nodefit_rankings_fitness
GROUP BY user_id
) AS lookup
ON lookup.user_id = a.user_id
AND
lookup.MAXSCORE = a.score
ORDER BY score DESC,
datetime_added DESC
This generates this ranking:
The problem is that if a user has achieved the same maximum score a number of times, he will appear multiple times in the ranking. The query must be adjusted so that when a user has the same maximum score a few times, only the result of the last attempt (based on the datetime_added column) is displayed in the rankings.
Unfortunately, I cannot find a solution myself. Help is certainly appreciated.
If you care about performance, you should also try a correlated subquery:
SELECT id, workout_id, level_id, a.user_id, total_time, score, datetime_added
FROM nodefit_rankings_fitness nrf
WHERE nrf.id = (SELECT TOP (1) nrf2.id
FROM nodefit_rankings_fitness nrf2
WHERE nrf2.user_id = nrf.user_id
ORDER BY nrf2.score DESC
)
ORDER BY score DESC, datetime_added DESC;
In particular, this can take advantage of an index on nodefit_rankings_fitness(user_id, score desc, id).
Window functions make stuff like this easy. Something like:
SELECT id, workout_id, level_id, user_id, total_time, score, datetime_added
FROM (SELECT *, row_number() OVER (PARTITION BY user_id ORDER BY score DESC, datetime_added DESC) AS rn
FROM nodefit_rankings_fitness) AS a
WHERE rn = 1
ORDER BY score DESC, datetime_added DESC;

MS SQL add max()-1 to qyery

how to add to the query max(o.Acct)-1 rows. I need to visualize the last two o.Acct rows. My query is currently showing only the max(o.Acct)
SELECT Max(o.Acct) AS [MaxAcct],o.ObjectID,o.Opertype
FROM Operations o
GROUP By o.ObjectID,o.Opertype
If you want to see the last two rows (per group), you're better off using ROW_NUMBER() rather than GROUP BY.
SELECT
*
FROM
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY ObjectID,
Opertype
ORDER BY Acct DESC
)
AS sequence_id
FROM
Operations
)
sortedOperations
WHERE
sequence_id <= 2
ORDER BY
ObjectID,
Opertype,
Acct
If you want the last two of something, I'm thinking order by and top. Something like this:
select top (2) o.*
from Operations o
order by o.acct desc;

Display the top two most popular activities across all reservations

The Table is
SUPERVISION (ResNo, ActivityID, SupervisorID, Day, Time)
I have done something like this but it is wrong
SELECT COUNT(S.Res, S.ActivityID) AS PopularActivities
FROM Supervision S
WHERE rownum = 2;
ORDER BY COUNT(*) DESC;
or
SELECT S.ResNo, S.ActivityID
FROM Supervision S
WHERE (rank() over (order by count(*) DESC) as RNK
from Supervision S) AND rnk = 2;
You need to put it in a subquery:
SELECT *
FROM (
SELECT
ActivityID, COUNT(*) AS Cnt
FROM Supervision
GROUP BY ActivityID
ORDER BY Cnt DESC
) t
WHERE rownum <= 2
Alternatively, you can use RANK to achieve the same result:
SELECT *
FROM (
SELECT
ActivityID,
RANK() OVER(PARTITION BY ActivityID ORDER BY COUNT(*) DESC) AS rnk
FROM Supervision
GROUP BY ActivityID
) t
WHERE rnk <= 2
Try this
SELECT *
FROM (
SELECT
ActivityID, COUNT(*) AS top
FROM Supervision
GROUP BY ActivityID
ORDER BY top DESC
) t
limit 0,2
For me, what I did is this:
ORDER BY TIME DESC
You want the two most popular activities across all reservations.
This means that you want to count the reservations of each activity type, and take the two with the highest count.
Another way to say it is, you want to group the reservations by activity, count them, order the result decrescently, and take the first two
It looks like you are using Microsoft TSQL syntax, so it should look like this:
SELECT TOP 2 ActivityID, COUNT(*)
FROM SUPERVISION
GROUP BY ActivityID
ORDER BY COUNT(*) DESC

How do I group by the count value in sql

Say I have
SELECT *, count(userid)
FROM stars
GROUP by userid
How do I change the GROUP by userid to group by the count(userid)
I searched google but couldn't find anything.
For those stuck: I want to count how many users have X amount of stars.
Use two levels of group by:
select cnt, count(*), min(userid), max(userid)
from (select userid, count(*) as cnt
from stars
group by userid
) u
group by cnt
order by cnt;
I call this type of query a "histogram of histograms" query. I include the min() and max() values because I often find those useful for further investigation.