Get max with one count - sql

I use a sql request to get the number message by user by forum.
SELECT count(idpost), iduser, idforum
FROM post
group by iduser, idforum
And I get this result:
But I want to get the better poster in one forum. How can I get it?
I want to get the user who has the most number of post in ONE forum like this :

According to the edited question:
Please try the query below. What we need is a subquery finding max(idpost) based on idforum. Think the query below:
select max(idpost) as IDPOST,idforum
from post
group by idforum
What this query is supposed to do is to find the number of posts by a user on a forum. So it should present you an output like:
idpost idforum
3 1
2 2
3 4
Then we need to find the related iduser for this rows as:
select p2.IDPOST, p1.iduser, p2.idforum
from post p1 inner join
( --the query above comes here as subquery.
select max(idpost) as IDPOST,idforum
from post
group by idforum
) p2 on p1.idforum = p2.idforum and p1.idpost = p2.IDPOST
What it is doing is to match the data from your main table with the temprorary data coming from your subquery based on idforum and idpost values and adding iduser value from your original table.
idpost iduser idforum
3 2 1
2 6 2
3 2 4

Well assuming you supply the idForum of the forum in question.........just get the top row of your query ordered by the count desc
SELECT TOP 1 * FROM
(
SELECT count(idpost),iduser,idforum FROM post
GROUP BY iduser,idforum
) PostsCount
WHERE PostsCount.idForum = #theForumIdIamLookingFor
ORDER BY count DESC

SELECT MAX(CN),idforum,Max(iduser) iduser
FROM (
SELECT count(idpost) CN,iduser,idforum
FROM post
Group By iduser,idforum
) A Group By idforum

If your DBMS supports RANK/ROW_NUMBER it simple:
select cnt, iduser, idforum
from
(
SELECT count(idpost) as cnt, iduser, idforum,
RANK() OVER (PARTITION BY idforum ORDER BY count(idpost) DESC) as rnk
FROM post
group by iduser, idforum
) dt
where rnk = 1
This might return more than one row per forum if multiple users share the same count. Switch to ROW_NUMBER if you want to return only one (but random) row.

SELECT count(idpost) MAX,iduser,idforum FROM post
ORDER BY count(idpost) DESC group by iduser,idforum
Or, you can do a nested query. But, I prefer this.
You can easily pick the first result as MAX

Related

SQL: Deleting Duplicates using Not in and Group by

I have the following SQL Syntax to delete duplicate rows, but never are any rows affected.
DELETE FROM content_stacks WHERE id NOT IN (
SELECT id
FROM content_stacks
GROUP BY user_id, content_id
);
The subquery itself is returning the id list of first entries correctly.
SELECT id
FROM content_stacks
GROUP BY user_id, content_id
When I'm inserting the results list as a string it is working, too:
DELETE FROM content_stacks WHERE id NOT IN (239,231,217,218,219,232,233,220,230,226,234,235,224,225,221,223,222,227,228,229,236,237,238,216,208,209,210,204,211,212,242,203,240,201,241,205,206,207,213,214,215);
I checked many similar examples and this should be working in my opinion. What am I missing?
First find first rows using ROW_NUMBER Then delete record with row number greater than 1:
WITH CTE AS (
SELECT id , ROW_NUMBER() OVER(PARTITION BY user_id, content_id, ORDER BY id) rn
FROM content_stacks
)
DELETE cs
FROM content_stacks cs
INNER JOIN CTE ON CTE.id = cs.id
WHERE rn > 1
Am sorry to ask but if your deleting why would u need to group the records.
Are not just increasing the runtime.
The code from Meyssam Toluie is not working as it is but I made a similar solution with the same idea with rownumbers:
DELETE FROM content_stacks WHERE id IN
(SELECT id FROM (
SELECT id, ROW_NUMBER() OVER(PARTITION BY user_id, content_id)row_num
FROM content_stacks
) sub
WHERE row_num > 1)
This is working for me now.
My first command did not work because: The group by command does not show all ids in the output, but they are still there, so in fact all ids were returned in the NOT IN id-list. The row number seems to be the easiest way for this problem.

Selecting top 10 counts in SQLite

I have a table which records questions, their answers, and their authors. The column names are as follows:
id, question, answers, author
I would like to get a list of top 10 authors who have written the most questions. So it would need to first count the number of questions each author has written then sort them by the count then return the top 10.
This is in SQLite and I'm not exactly sure how to get the list of counts. The second part should be fairly simple as it's just an ORDER BY and a LIMIT 10. How can I get the counts into a list which I can select from?
SELECT BY COUNT(author)
,author
FROM table_name
GROUP BY author
ORDER BY COUNT(author) DESC LIMIT 10;
You can apply an order by clause to an aggregate query:
SELECT author, COUNT(*)
FROM mytable
GROUP BY author
ORDER BY 2 DESC
LIMIT 10
You could wrap your query as a subquery and then use LIMIT like this:
SELECT *
FROM (
SELECT author
,COUNT(*) AS cnt
FROM mytable
GROUP BY author
) t
ORDER BY t.cnt DESC
LIMIT 10;

Highest Record for a set user

Hope someone can help.
I have been trying a few queries but I do not seem to be getting the desired result.
I need to identify the highest ‘’claimed’’ users within my table without discarding the columns from the final report.
The user can have more than one record in the table, however the data will be completely different as only the user will match.
The below query only provides me the count per user without giving me the details.
SELECT User, count (*) total_record
FROM mytable
GROUP BY User
ORDER BY count(*) desc
Table:
mytable
Column 1 = User Column 2 = Ref Number Column 3 = Date
The first column will be the unique identifier, however the data in the other columns will differ, therefore it needs to descend the highest claimed user with all the relevant rows to the user to the least claimed user.
User|Ref Num|Date
1|a|20150317
1|b|20150317
2|c|20150317
3|d|20150317
4|e|20150317
1|f|20150317
4|e|20150317
The below data is how the values should be returned.
User|Ref Num|Date|Count
1|a|20150317|3
1|b|20150317|3
1|f|20150317|3
2|c|20150317|1
3|d|20150317|1
4|e|20150317|2
4|e|20150317|2
Hope it makes sense.
Thank you
As you're using MSSQL you can use the OVER() clause like so:
SELECT [user], mt.ref_num, mt.[date], COUNT(mt.[user]) OVER(PARTITION BY mt.[user])
FROM myTable mt
More about the OVER clause can be found here: https://msdn.microsoft.com/en-us/library/ms189461.aspx
As per your comment you can use the wildcard * like so:
SELECT mt.*, COUNT(mt.[user]) OVER(PARTITION BY mt.[user])
FROM myTable mt
This would get you every column as well as the result of the count.
If you want to order by the number of record for each user, then use window functions instead of aggregation:
SELECT t.*
FROM (SELECT t., count(*) OVER (partition by user) as cnt
FROM mytable t
) t
ORDER BY cnt DESC, user;
Note that I added user to the order by so users with the same count will appear together in the list.
You could use an outer apply if your version of SQL Server supports it:
SELECT [User], [Ref Num], Date, total_record
FROM mytable M
OUTER APPLY (
SELECT count(*) total_record
FROM mytable
WHERE [user] = M.[user]
GROUP BY [user]
) oa
ORDER BY total_record desc, [user]
Note that user is a reserved keyword in MSSQL and you need to enclose it in either brackets [user] or double-quotes "user".
This would produce an output like:
user Ref Num Date total_record
1 a 2015-03-17 3
1 b 2015-03-17 3
1 f 2015-03-17 3
4 e 2015-03-17 2
4 e 2015-03-17 2
2 c 2015-03-17 1
3 d 2015-03-17 1
Note that the answers using the count(*) OVER (partition by [user]) construct are more efficient though.
Most simple way would be to use window fuction.
SELECT table.*, COUNT(*) OVER (PARTITION BY user)
FROM nameoftable table -- this is an alias
ORDER BY user, ref_num
This also seem to fit your need.
This is the old way of doing it. Where possible you should use OVER but as other people have answered with that I thought I'd throw this one into the mix.
SELECT
T.[User]
,T.[Ref Num]
,T.[Date]
,(SELECT count(*) from [myTable] T2 where T2.[User] = T.[USER]) as [Count]
FROM [mytable] T
ORDER BY [Count] DESC

Retrieve the most used 10 records

I want to retrieve the most used 10 records in a field in my database. I used this query but it didn't work !
select Top 10 tag from articles order by count(tag) desc ;
This is the error I'm getting:
Column 'article.tags' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Try this:
SELECT TOP 10 tag, COUNT(tag) tagCount
FROM articles
GROUP BY tag
ORDER BY tagCount DESC
Select TOP 10 tag From
(
Select tag,count(*) as total
From articles
Group by tag
) z
order by total Desc
You can't identify with a simple select top statement. I would suggest you to involve one more table to keep track of id of most selected record something like this:
ArticleId Counter LastUsed
--------------------------
1 5 11/12/2013
3 11 10/12/2013 // and so on
Using this table join with your main table and pick the mostly used top 10 ids, based on their counter.
Select * From MainTable Where ArticleId in (
Select Top(10) ArticleId
From Table
Order By Counter Desc)

SQL - Order by the numbers of rows?

So I have a table with 5 columns: id, user_id, news_id, comment and date. Every time a user posts something on the news's comment area the data is inserted into this table.
Now I am trying to make a top poster function that will display the people with the mosts comments posted.
I would like to know how to order the result from this table based on how many times that user_id is present in the table.
For example:
1 - 134(user_id) -> 20 posts(that's how many times this user_id was found in the table.)
2 - 123 -> 19
3 - 168 -> 15
and so on.
Thanks in advance.
SELECT user_id, COUNT (*) as comments
FROM table
GROUP BY user_id
ORDER BY comments DESC
TSQL
select userID, count(*)
from userIDtable
group by userID
order by count(*) desc, userID asc
I think you are confusing rows with columns, but never mind. This is easy to do:
SELECT
user_id,
COUNT(*) posts
FROM
comments
GROUP BY
user_id
ORDER BY
posts DESC
SELECT count(user_id) C, user_id FROM RECORDS ORDER BY C LIMIT 5
"So I have a table with 5 rows: id, user_id, news_id, comment and date. Every time a user posts something on the news's comment area the data is inserted into this table. "
In this answer I'll assume you have meant 5 columns above.
select user_id, count(*) num from tableName group by user_id order by num desc;