I have a table for example:
Names Details
--------------
wilson admin
david member
wilson admin
wilson admin
sam member
david member
Now what i want to achieve is show a table like this
Names Details count
--------------------
wilson admin 3
david member 2
sam member 1
I want to show the names according to how many times they appear
SELECT Name, Detail, COUNT(*) as Count
FROM MyTable
GROUP BY Name, Detail
ORDER BY Count DESC;
Since you have more than one column in your output table SELECT, you should group by both columns.
I found the answer already
SELECT names, COUNT(names) AS count
FROM my_table
GROUP BY names ORDER BY count DESC
Try this, use the GROUP BY and COUNT
SELECT Names, Details, COUNT(NAMES) as `count` FROM `table` GROUP BY `Names`
Related
This question already has answers here:
Get top n records for each group of grouped results
(12 answers)
Closed 11 months ago.
I have a 'family' table, with the following columns:
first name
family name
age
I want to query this table such that only ONE member of each family will show up on my result list, and that member must be the oldest, and also limit the result to 25.
Example: imagine the following table with ~500k records.
first_name
last_name
age
john
smith
5
mary
smith
10
jack
son
10
joe
daught
10
The expected result list should return [{mary, smith, 10}, {jack, son, 10}, {joe, daught, 10}].
My current solution is basically to pull the whole table, then remove the 'dupes' manually based on age and last name. While this is "ok", once my dataset gets bigger, it's possibly just wasted processing time.
Is this possible using SQL?
You can use ROW_NUMBER() to assign a numeric value by age (oldest to youngest) withing each family. Then you can pick the first one for each family. For example:
select *
from (
select t.*,
row_number() over(partition by last_name order by age desc) as rn
from t
) x
where rn = 1
When using GROUP BY you will need to use an aggregator (MIN(), MAX(), FIRST n, LAST n, etc.) in the SELECT section:
SELECT MAX(u.age), u.last_name
FROM users AS u
GROUP BY u.last_name
select first_name from table_name group by last_name having max(age)
I want to concatenate fields intersected part of the same table
id user_id user_ip
4 971 108.54.218.114
5 972 108.54.218.114
6 973 108.54.218.114
7 974 108.54.218.114
8 975 107.222.159.246
9 975 98.54.818.133
In the example above, we can see that the user with the IP address (108.54.218.114) address to create multiple accounts with the following account IDs (971, 972, 973, 974), but also that the user with the account ID (975) is connect from the following IP addresses (107.222.159.246, 98.54.818.133)
I want to format the results like this
user_id user_ip
971,972,973,974 108.54.218.114
975 107.222.159.246, 98.54.818.133
MySQL
SELECT
GROUP_CONCAT(DISTINCT users_log.user_id) AS ID_LOG,
GROUP_CONCAT(DISTINCT users_log.user_ip) AS IP_LOG
FROM users_log
GROUP BY users_log.user_id
ORDER BY users_log.user_id DESC
If anyone can help me?
Thank you in advance for your help
There is another recent question (which I can't find) on SO very close to this. I asked about the intersecting row because of the (for lack of better term) recursiveness of this type of solution.
Here is SQL to give you your exact answer for that exact sample set.
SELECT user_id, GROUP_CONCAT(DISTINCT user_ip) AS user_ip
FROM users_log
GROUP BY user_id
HAVING COUNT(*) >1
UNION
SELECT GROUP_CONCAT(DISTINCT user_id) AS user_id, user_ip
FROM users_log
GROUP BY user_ip
HAVING COUNT(*) >1;
I have a column that takes user names. How can I count the number of instances of a users name. For example I have 10 rows and in column username i want to count all names that show up multiple times. I would like to build a list of the top contributors to my database. So if username alex shows up 5 times and jeff shows up 3 and april shows up 2 times i will count this and from that I can build my list.
Try GROUP BY:
SELECT username, COUNT(*) AS user_count
FROM yourtable
GROUP BY username
ORDER BY user_count DESC
Try something like
SELECT USER_NAME, COUNT(USER_NAME) FROM YOUR_TABLE GROUP BY USER_NAME;
If you want to get a count of all the usernames then you just do the following SQL:
Select Count(*) from tablename
If you want to get just the count of unique usernames
Select Count(*) from tablename Group by username
I can't seem to find a suitable solution for the following (probably an age old) problem so hoping someone can shed some light. I need to return 1 distinct column along with other non distinct columns in mySQL.
I have the following table in mySQL:
id name destination rating country
----------------------------------------------------
1 James Barbados 5 WI
2 Andrew Antigua 6 WI
3 James Barbados 3 WI
4 Declan Trinidad 2 WI
5 Steve Barbados 4 WI
6 Declan Trinidad 3 WI
I would like SQL statement to return the DISTINCT name along with the destination, rating based on country.
id name destination rating country
----------------------------------------------------
1 James Barbados 5 WI
2 Andrew Antigua 6 WI
4 Declan Trinidad 2 WI
5 Steve Barbados 4 WI
As you can see, James and Declan have different ratings, but the same name, so they are returned only once.
The following query returns all rows because the ratings are different. Is there anyway I can return the above result set?
SELECT (distinct name), destination, rating
FROM table
WHERE country = 'WI'
ORDER BY id
Using a subquery, you can get the highest id for each name, then select the rest of the rows based on that:
SELECT * FROM table
WHERE id IN (
SELECT MAX(id) FROM table GROUP BY name
)
If you'd prefer, use MIN(id) to get the first record for each name instead of the last.
It can also be done with an INNER JOIN against the subquery. For this purpose the performance should be similar, and sometimes you need to join on two columns from the subquery.
SELECT
table.*
FROM
table
INNER JOIN (
SELECT MAX(id) AS id FROM table GROUP BY name
) maxid ON table.id = maxid.id
The problem is that distinct works across the entire return set and not just the first field. Otherwise MySQL wouldn't know what record to return. So, you want to have some sort of group function on rating, whether MAX, MIN, GROUP_CONCAT, AVG, or several other functions.
Michael has already posted a good answer, so I'm not going to re-write the query.
I agree with #rcdmk . Using a DEPENDENT subquery can kill performance, GROUP BY seems more suitable provided that you have already INDEXed the country field and only a few rows will reach the server. Rewriting the query giben by #rcdmk , I added the ORDER BY NULL clause to suppress the implicit ordering by GROUP BY, to make it a little faster:
SELECT MIN(id) as id, name, destination as rating, country
FROM table WHERE country = 'WI'
GROUP BY name, destination ORDER BY NULL
You can do a GROUP BY clause:
SELECT MIN(id) AS id, name, destination, AVG(rating) AS rating, country
FROM TABLE_NAME
GROUP BY name, destination, country
This query would perform better in large datasets than the subquery alternatives and it can be easier to read as well.
I have two tables, one is a table of names with a category tag and the other is a table of scores for each name
ID Name Category
1 Dave 1
2 John 1
3 Lisa 2
4 Jim 2
and the score table is
PersonID Score
1 50
2 100
3 75
4 50
4 75
I would then like a query that returned something like
Category TotalScore Names
1 150 Dave, John
2 200 Lisa, Jim
Is this possible to do with one query?
I can get the totals with a sum query and grouping by category but cannot see a way to get the names as I would like.
Many thanks
You need to use group_concat:
select Category, sum(Score) as TotalScore, group_concat(Name) as Names from categories
join scores on scores.category = categories.category
group by category
Or even better:
group_concat(DISTINCT Name ORDER BY Name ASC SEPARATOR ',') as names
Just add group_concat(Name) as names into your sum query.
Here is a solution working for Postgres (which doesn't have a group_concat() function):
select category, sum(score) as TotalScore, array(select id from perso where category=P.category order by id) as Names from perso P JOIN scores S ON S."PersonID" = P.id GROUP BY category;
(I know this was a MySQL question, but nonetheless someone might google it up but needs an answer for Postgres :) )