Determine total amount of top result returned - mysql

I would like to determine two things from a single query:
Most prevalent column in a table
The amount of times such column was located upon querying the table
Example Table:
user_id some_field
1 data
2 data
1 data
The above would return user_id # 1 as being the most prevalent in the table, and it would return (2) for the total amount of times that it was located in the table.
I have done my research and I came across two types of queries.
GROUP BY user_id ORDER BY COUNT(*) DESC
SUM
The problem is that I can't figure out how to use these two queries in conjunction with one another. For example, consider the following query which successfully returns the most prevalent column.
$top_user = "SELECT user_id FROM table_name GROUP BY user_id ORDER BY COUNT(*) DESC";
The above query returns "1" based on the example table shown above. Now, I would like to be able to return "2" for the total amount of times the user_id (1) was found in the table.
Is this by any chance possible?
Thanks,
Evan

You can include count(*) in the SELECT list:
SELECT user_id, count(*) as totaltimes from table_name
GROUP BY user_id ORDER BY count(*) DESC;
If you want only the first one:
SELECT user_id, count(*) as totaltimes from table_name
GROUP BY user_id ORDER BY count(*) DESC LIMIT 1;

Related

Mysql query to find all in row when value in certain column appears

In my database table, I have a value denoted userID. The value user ID may appear multiple times. I am trying to write a query that will either return all data in the row of that table if the value in userID appears 3 or more times. Alternatively, a query that return a list of all userIDs that appear 3 or more times.
Here is what I have now:
SELECT
*
FROM
myTable
WHERE
userID IN (SELECT
userID
FROM
myTable
GROUP BY userID
HAVING COUNT(*) > 2)
GROUP BY userID
This query kinda works, but some of the rows returned only have a single or double occurrence.
Any ideas on how I can modify this query so that it works?
You made things harder tnen they are, it's all simple:
SELECT
userID
FROM
myTable
GROUP BY userID
HAVING COUNT(userID) > 2)
This is if you only need ID's, else you should use this in place of SELECT statement in your WHERE part
Add the rest of your columns in the GROUP BY userID for all of the rows and youre super close with the list of userID's. This'll give you the UserID's:
SELECT userID FROM your_table
GROUP BY userID
HAVING COUNT(*) >= 3
and this will be for all:
SELECT
*
FROM
your_table
WHERE
userID IN (SELECT
userID
FROM
your_table
GROUP BY userID
HAVING COUNT(*) >= 3)
GROUP BY UserID, column_name1, column_name2

Calculate Average of Text Value Mysql [duplicate]

Using PHP and MySQL, I want to query a table of postings my users have made to find the person who has posted the most entries.
What would be the correct query for this?
Sample table structure:
[id] [UserID]
1 johnnietheblack
2 johnnietheblack
3 dannyrottenegg
4 marywhite
5 marywhite
6 johnnietheblack
I would like to see that "johnnietheblack" is the top poster, "marywhite" is second to best, and "dannyrottenegg" has the least
Something like:
SELECT COUNT(*) AS `Rows`, UserID
FROM `postings`
GROUP BY UserID
ORDER BY `Rows` DESC
LIMIT 1
This gets the number of rows posted by a particular ID, then sorts though the count to find the highest value, outputting it, and the ID of the person. You'll need to replace the 'UserID' and 'postings' with the appropriate column and field though.
I believe this should work...
SELECT user_id, COUNT(*) FROM postings ORDER BY COUNT(*) GROUP BY user_id LIMIT 1
Assuming posting is a tuple (user_id, recipient_user_id), where each row represents one posting, from user_id to recipient_user_id:
select user_id, count(*) as posts
from postings
group by user_id
having count(*) = max(count(*)) ;

Aggregate function in BETWEEN and AND

I have joined 3 tables in my query. In my Inventory db,Price is taken from table c and quantity is taken from table b. How can I show the records list of users who have ordered between the given value and maximum value of the column.
I am using below query in mysql to retrieve records. As expected it shows error. Any help will be highly appreciated
SELECT .... GROUP BY userid HAVING SUM(c.`price` * b.`quantity`) BETWEEN 9000 AND MAX(SUM(c.`price` * b.`quantity`))
If I understand correctly you don't need BETWEEN. Try it this way
SELECT ....
GROUP BY userid
HAVING SUM(c.`price` * b.`quantity`) >= 9000
In case you wondered you can't chain aggregate functions. And even if you could it wouldn't make sense because you group by userid, but trying to get MAX of SUM from all users. In order for this to work you should've used a subquery to get max value e.g.
SELECT ....
GROUP BY userid
HAVING SUM(c.`price` * b.`quantity`) =
(
SELECT MAX(total) total
FROM
(
SELECT SUM(c.`price` * b.`quantity`) total
GROUP BY userid
) q
)

MySQL: Remove rows from a GROUP BY result if it only grouped 1 row

When selecting data, I'm able to show how many rows were grouped from using GROUP BY by running:
SELECT id, created, COUNT(id) `count` FROM table
GROUP BY id
LIMIT 0,30
The count field easily outputs how many rows were affected by the GROUP BY. In MySQL is it possible to automatically not include any row which only has a count value of 1?
You should consider using a HAVING clause which lets you add conditions after the grouping has been done.
SELECT id, created, COUNT(id) cnt FROM table
GROUP BY id
HAVING cnt > 1
LIMIT 0,30
Another thing to mention is that the grouping might not be correct. If you group by id and you select id, created then the value for created is undetermined. MySQL will choose any of them for a given id if they differ. You might be interested in grouping by that field too or applying an aggregate function (eg: max(created)).
A second thing to mention is that COUNT(id) won't count the amount of rows but rather the amount of rows that have id not null. If id is never null then it would result in the same value as doing count(*).
Yes. You can use HAVING to limit the results of an aggregate function like COUNT (MAX,MIN,SUM, etc).
SELECT id, created, COUNT(id) `count`
FROM table
GROUP BY id
HAVING COUNT(id) > 1
LIMIT 0,30
Show the manual and find HAVING
... HAVING COUNT(id) > 1
http://dev.mysql.com/doc/refman/5.1/de/select.htmlhavinh

MySQL Query to find row duplicates based on condition with limit

I have two tables:
Members:
id username
Trips:
id member_id flag_status created
("YES" or "NO")
I can do a query like this:
SELECT
Trip.id, Trip.member_id, Trip.flag_status
FROM
trips Trip
WHERE
Trip.member_id = 1711
ORDER BY
Trip.created DESC
LIMIT
3
Which CAN give results like this:
id member_id flag_status
8 1711 YES
9 1711 YES
10 1711 YES
My goal is to know if the member's last three trips all had a flag_status = "YES", if any of the three != "YES", then I don't want it to count.
I also want to be able to remove the WHERE Trip.member_id = 1711 clause, and have it run for all my members, and give me the total number of members whose last 3 trips all have flag_status = "YES"
Any ideas?
Thanks!
http://sqlfiddle.com/#!2/28b2d
In that sqlfiddle, when the correct query i'm seeking runs, I should see results such as:
COUNT(Member.id)
2
The two members that should qualify are members 1 and 3. Member 5 fails because one of his trips has flag_status = "NO"
You could use GROUP_CONCAT function, to obtain a list of all of the status ordered by id in ascending order:
SELECT
member_id,
GROUP_CONCAT(flag_status ORDER BY id DESC) as status
FROM
trips
GROUP BY
member_id
HAVING
SUBSTRING_INDEX(status, ',', 3) NOT LIKE '%NO%'
and then using SUBSTRING_INDEX you can extract only the last three status flags, and exclude those that contains a NO. Please see fiddle here. I'm assuming that all of your rows are ordered by ID, but if you have a created date you should better use:
GROUP_CONCAT(flag_status ORDER BY created DESC) as status
as Raymond suggested. Then, you could also return just the count of the rows returned using something like:
SELECT COUNT(*)
FROM (
...the query above...
) as q
Although I like the simplicity of fthiella's solution, I just can't think of a solution that depends so much on data representation. In order not to depend on it you can do something like this:
SELECT COUNT(*) FROM (
SELECT member_id FROM (
SELECT
flag_status,
#flag_index := IF(member_id = #member, #flag_index + 1, 1) flag_index,
#member := member_id member_id
FROM trips, (SELECT #member := 0, #flag_index := 1) init
ORDER BY member_id, id DESC
) x
WHERE flag_index <= 3
GROUP BY member_id
HAVING SUM(flag_status = 'NO') = 0
) x
Fiddle here. Note I've slightly modified the fiddle to remove one of the users.
The process basically ranks the trips for each of the members based on their id desc and then only keeps the last 3 of them. Then it makes sure that none of the fetched trips has a NO in the flag_status. FInally all the matching meembers are counted.