PHP SQL Query to get the most common value in the table - php

I'm trying to have my query count the rows and have it return the most common name in that list, then from that it counts how many times that name appears and outputs the name and the amount of times its there
This is the code I'm using:
$vvsql = "SELECT * FROM votes WHERE sid=? ORDER BY COUNT(*) DESC LIMIT 1";
$vvresult = $db->prepare($vvsql);
$vvresult->execute(array($_GET['id']));
$vvcount = $vvresult->rowCount();
foreach ($vvresult->fetchAll(PDO::FETCH_ASSOC) as $row) {
echo $row['username'];
echo $vvcount;
}
However, it just displays the first username in the table and counts up the entire table. I'm pretty new to this so I'm sorry if this is a bad post or if it didn't make much sense.

You would seem to want:
SELECT name, COUNT(*) as cnt
FROM votes
GROUP BY name
ORDER BY COUNT(*) DESC
LIMIT 1;
Note the GROUP BY. You may also want to filter by sid but your question makes no mention of that.

select username, count(*) as c
FROM votes
GROUP BY username
ORDER BY c DESC

Related

Get the most common value from MySQL column in PHP

I have a simple table in phpmyadmin called name with only 1 column id which is look like this
id
--------
a
b
a
a
a
a
b
Now i want to show most used id on my PHP page.
Here is my code:
$sql_a = mysql_query(SELECT id FROM name WHERE id='a');
$count_a = mysql_num_rows($sql_a);
$sql_b = mysql_query(SELECT id FROM name WHERE id='b');
$count_b = mysql_num_rows($sql_b);
if($count_a > $count_b)
{
$most_used_id = "A";
}
else
{
$most_used_id = "B";
}
echo "<h1>MOST USED ID IS $most_used_id</h1>";
Currently I have only 2 types of id but in future I will have multiples (maybe 300+) id's, so is there a way to make query dynamic and get only most used value
That's very redundant code. You'd be better off with
SELECT id, count(id) AS cnt
FROM name
ORDER BY cnt DESC
GROUP BY id
LIMIT 1
that'll give you the "most popular" id value, and just how popular it is. If you need to get the count of all the ids, then remove the limit line.
Try the following query:
select id, count(id) cnt
from name
group by id
order by cnt desc
limit 1

SQL Order By id and Count star not working

I would like to get number of all records and get last record :
$sql_count_sms = "SELECT count(*) as total,content,id FROM android_users_sms WHERE user_id=$id ORDER BY id DESC";
$result_count_sms = mysql_query($sql_count_sms);
$row_num_sms = mysql_fetch_assoc($result_count_sms);
$num_sms = $row_num_sms['total'];
$last_my_sms = $row_num_sms['content'];
I can get number of records but I can't get last content record .
It returns first record !
Where is my wrong ?
Below codes works fine, but I think count(*) is faster than mysql_num_rows .
$sql_count_sms = "SELECT content,id FROM android_users_sms WHERE user_id=$id ORDER BY id DESC";
$result_count_sms = mysql_query($sql_count_sms);
$row_num_sms = mysql_fetch_assoc($result_count_sms);
$num_sms = mysql_num_rows($result_count_sms);
$last_my_sms = $row_num_sms['content'];
Any solution?
The grain of the two results you want is not the same. Without using a sub-query you can't combine an aggregate and a single row into the same result.
Think of the grain as the base unit of the result. The use of GROUP BY and aggregate functions can influence that "grain"... one result row per row on table, or is it grouped by user_id etc... Think of an aggregate function as a form of grouping.
You could break it out into two separate statements:
SELECT count(*) as total FROM android_users_sms WHERE user_id = :id;
SELECT * FROM android_users_sms WHERE user_id = :id ORDER BY id DESC LIMIT 1;
Also, specific to your question, you probably want a LIMIT 1 in combination with the ORDER BY to get just the last row.
Now, counter intuitively perhaps, this should also work:
SELECT count(*), content, id
FROM android_users_sms
WHERE user_id = :id
GROUP BY id, content
ORDER BY id
LIMIT 1;`
This is because we've changed the "grain" with the GROUP BY. This is the real nuance and I feel like this could probably be explained better than I am doing now.
You could also do this with a sub query like so:
SELECT aus.*,
(SELECT count(*) as total FROM android_users_sms WHERE user_id = :id) AS s1
FROM android_users_sms AS aus
WHERE user_id = :id ORDER BY id DESC LIMIT 1;

How can I order by count in mysql when the count need data to calculate from this select statement?

Look at my code, I want the select statement order by the count percentage after I fetch the data from this select statement, obviously, it's not logical. What can I do? Help, appreciate.
<?php
//myslq connection code, remove it because it's not relate to this question
$stm =$db->prepare("SELECT id ,term_count, COUNT(user_id) as count FROM sign WHERE term IN (:term_0,:term_1) GROUP BY user_id ORDER by count DESC");
//trying replace order by count with $combine_count, but it's wrong
$term_0="$term[0]";
$term_1="$term[1]";
$stm->bindParam(":term_0", $term_0);
$stm->bindParam(":term_1", $term_1);
stm->execute();
$rows = $stm->fetchALL(PDO::FETCH_ASSOC);
foreach ($rows as rows) {
$count=$rows['count'];
$term_count_number=$rows['term_count'];
$count_percentage=round(($count/$count_user_diff)*100);
$count_key_match=round(($count/$term_count_number)*100);
$combine_count=round(($count_percentage+$count_key_match)/2);
//issue is here, I want the select statement order by $combine_count
}
?>
SELECT id ,term_count, COUNT(user_id) as `count`
FROM sign
WHERE term IN (:term_0,:term_1)
GROUP BY user_id
ORDER by `count` DESC");
Since "count" is a function, it would be better to put backtics around the non-function "counts", as done above.
GROUP BY should list the field not aggregated. Otherwise, it does not know which id and term_count to fetch. So, depending on what you are looking for,
Either do
SELECT user_id, COUNT(*) as `count` -- I changed this line
FROM sign
WHERE term IN (:term_0,:term_1)
GROUP BY user_id
ORDER by `count` DESC");
or do
SELECT id ,term_count, COUNT(*) as `count`
FROM sign
WHERE term IN (:term_0,:term_1)
GROUP BY id ,term_count -- I changed this line
ORDER by `count` DESC");
SQL Syntax Logic
SELECT column1, count(column1) AS amount
FROM table_name
GROUP BY column1
ORDER BY amount DESC
LIMIT 12

select 3 rows from mysql table, then get each row's specific column

Select 3 rows from table1
Get a specific column data out of each row.
Then use that each column data obtained , to make a query again to get data from table2.
Store the data obtained in step 4 into a variable for each row.
Then put them in json array (table 1 , 3 rows + table 2's data(each of them).
I am building a rank table, it displays top 3 users with their rank name.
For example:
User1 has 2000 points , user 2 has 4000points , user 3 has 10k points , so the top 3 user is :
user 3 > user 2 > user 1
So , i want the php to go to 'users' table and get the top 3 members using this:
$query = mysql_query("SELECT * FROM users ORDER BY pts DESC LIMIT 3");
$rows = array();
while($r = mysql_fetch_assoc($query)) {
$rows[] = $r;
}
Table structure for 'user':
1.username(varchar)
2.pts(int)
After the rows are put into an array , how can i get 'points' for each of the row in that array.
Then go to 'rank' table to get their ranknames.
Table structure for 'rank':
1.rank(varchar)
2.pts(int)
Inside rank table there is 'pts' to let php choose compare which rank the user is at based on the points from each row of the array.
Normally i would use this if its only for 1 user , but for multiple users , im not sure:
$result = mysql_query("SELECT * FROM rank WHERE pts <= '$upts' ORDER BY pts DESC LIMIT 1")
or die(mysql_error());
Then after getting the rank for the top 3 users , php will now add the ranks to each of the user(row) in that array(of course , add it to the rank owner, not just simply place it in).
Then JSON encode it out.
How can i do this?
I am not sure if this is what you want. That is combine the two query into one query. Please take a look at http://sqlfiddle.com/#!2/ad419/8
SELECT user.username,user.pts,rank.rank
FROM user LEFT JOIN rank
ON user.pts <=rank.pts group by user.id
UPDATED:
For extracting top 3, could do as below;
SELECT user.username,user.pts,rank.rank
FROM user LEFT JOIN rank
ON user.pts <=rank.pts
GROUP BY user.id
ORDER BY pts DESC LIMIT 3
If i understand correctly, you need to get values from Rank and Users tables. In order to do that in just one query You need to add FK (Foreign Key) to the Rank table that points to a specific user in the Users table.
So you need to add userId to the Rank table and then you can run:
SELECT r.rank, u.points from users u,rank r where u.userId = r.userId
This is roughly what you need.
Not quite the answer to your exact question, but this might be of use to you: How to get rank using mysql query. And may even mean that you don't require a rank table. If this doesn't help, I'll check back later.
Use this query
$query = "SELECT
u.pts,
r.rank
FROM users as u
left join ranks as r
on r.pts = u .pts
ORDER BY pts DESC
LIMIT 3";
This will bring what you required without putting into an array
$rec = mysql_query($query);
$results = arrau();
while($row = mysql_fetch_row($rec)){
$results[] = $row;
}
echo json_encode($results);
It looks like what you're trying to do is retrieve the rank with the highest point requirement that the user actual meets, which isn't quite what everyone else is giving here. Fortunately it is easily possible to do this in a single query with a nice little trick:
SELECT
user.username,
SUBSTRING_INDEX(GROUP_CONCAT(rank.rank ORDER BY pts DESC),",",1) AS `rank`
FROM user
LEFT JOIN rank ON user.pts >= rank.pts
GROUP BY user.id
ORDER BY pts DESC
LIMIT 3
Basically what the second bit is doing is generating a list of all the ranks the user has achieved, ordering them by descending order of points and then selecting the first one.
If any of your rank names have commas in then there's another little tweak we need to add on, but I wouldn't have thought they would so I've left it out to keep things simple.

mysql select statement and limiting the number of records

I am coding a blog post kind of thing, where the author will post the article and it will be displayed in the front end, my problem starts for selecting the posts as i have to meet certain conditions for posting the news in the front end,
I have 4 fields in the database namely
title
pic_title
pic_brief
pic_detail
you guessed it right apart from the title table the rest of three will hold the path to the images in varchar datatype, which will be used to display as the post, the format of the front end is such that
a) there will be total of eight post
displaying in the front end (eight
entries from the database)
b) there will be three post on the top which will include the value from
the table title, pic_title and
pic_brief (total of 3 values)
c) and the rest five will contain just the title and pic_title
(excluding the three entries of top)
Please NOTE: i want the second query to exclude the top 3 record
which already exist in the top i.e
(first query = 3 post in descending
order, second query = 8 - first 3 = 5
post)
The Order of the Post i want is by id DESC
EDIT: I took the first query as
SELECT * FROM news ORDER BY id DESC LIMIT 3
Now if i take the same second query and try populating the values by desc order again the same records will be accessed
In simple words i want a query that will skip the last three records order by id DESC
How do i achieve this feat in PHP?
If you just want the SQL, here it is:
First query
SELECT * FROM `table` LIMIT 3
Second query
SELECT * FROM `table` LIMIT 3,5
(where table is the name of your table of course. Of course you may want to add some ORDER BY clause. To execute these queries in PHP, I suggest reading the manual. If you have any specific problems after doing so, then you can post a new question.
This is a situation where I'd likely opt to select all eight records at once - the less trips to the database, the better.
SELECT t.title,
t.pic_title,
t.pic_brief
FROM TABLE t
ORDER BY t.id DESC
LIMIT 8
...because the rest is just presentation:
$query = sprintf("SELECT t.title,
t.pic_title,
t.pic_brief
FROM TABLE t
ORDER BY t.id DESC
LIMIT 8");
// Perform Query
$result = mysql_query($query) or die( mysql_error() );
$rowcount = 1;
// Use result
while ($row = mysql_fetch_assoc($result)) {
if(rowcount <= 3) {
echo $row['title']
echo $row['pic_title']
echo $row['pic_brief']
} else {
echo $row['title']
echo $row['pic_title']
}
++$rowcount;
}
first query will be like this
"select title, pic_title , pic_brief from table_name order by post_id desc limit 0 , 3"
and rest of five will be
"select title, pic_title from table_name order by post_id desc limit 3 , 5"
second query will exclude the three results returned by first query...
If you want more perfection you can collect all three Ids returned by first query and can add NOT IN in second query.
"select title, pic_title from table_name where post_id not in (1,2,3) order by post_id desc limit 0 , 5";

Categories