PHP MySQL getting top five highest results.? - php

have a poll table which has 10 categories and I want to view the top 5 results from highest to lowest limit into 5 categories. How can I do this in php and mysql?
here are example tables
categories
id
category_name
Votes
id
category_id
user_id
Users
id
username
here is my sample query:
$q = mysql_query("SELECT * from categories");
while($data = mysql_fetch_array($q){
$votes = mysql_query("SELECT * from votes where category_id=".$data['id']."");
$data_vote = mysql_nuw_rows($votes);
echo $data['category_name']."has".$data_vote."Votes";
}
I want my output to be like this from the highest votes in a categories
category1 has 30 votes
category3 has 25 votes
category5 has 23 votes
category2 has 15 votes
category4 has 10 votes

Use:
$q = mysql_query("SELECT c.category_name,
COALESCE(COUNT(v.category_id), 0) AS cnt
FROM CATEGORIES c
LEFT JOIN VOTES v ON v.category_id = c.id
GROUP BY c.category_name
ORDER BY cnt DESC
LIMIT 5 ");
while($data = mysql_fetch_array($q) {
echo $data['category_name'] ." has ". $data['cnt'] ." votes"
}

That query should do it:
select c.category_name, count(v.id) as number_of_votes
from CATEGORIES c
left join VOTES v on v.category_id = c.id
group by c.id
order by number_of_votes desc
limit 5
(assuming your VOTES table primary key is "id"

Related

Getting only a random item of each category

Well i have two table, categories and items and i would like to get a random record of each of 10 random category.
tb_category
category_id PK
category_name
tb_items
item_id PK
category_id FK
My table tb_category has about 40 rows and tb_items has about 5k rows, i'm search performance.
SELECT * FROM
( SELECT c.category_id as cid, c.category_name, i.item_id FROM
tb_category c INNER JOIN
tb_items i ON c.category_id = i.category_id ORDER BY RAND() ) AS ShuffeledItems
GROUP BY ShuffeledItems.cid limit 10
I don't know if that is better way to do it.
Thanks.
I would be inclined to use a correlated subquery:
select c.*,
(select i.item_id
from items i
where i.category_id = c.category_id
order by rand()
limit 1
) as item_id
from tb_category c
order by c.id
limit 10;

Mysql - get last post from category

I have this structure (tables) of forum
I want to select last post (row from forum_post table) from category.
SQL so far:
SELECT * FROM table_post
WHERE topic_id = (SELECT MAX(id) FROM table_topic WHERE category_id = {$id})
ORDER BY id ASC LIMIT 1
Question: How to modify this select to achieve my goal?
Assuming that "last" means the biggest id, I would suggest order by and limit:
select fp.*
from forum_post fp join
forum_topic ft
on fp.topic_id = ft.id
where ft.category_id = $id
order by fp.id desc
limit 1;

sql1 to get names and sql2 to get Impressions, I need to sort names by Impressions

Hello I have this Project and I need to help me
$sql1 = "SELECT COUNT(*) as num FROM table1 where column1='1'";
$total_Results = mysql_fetch_array(mysql_query($sql1));
$total_Results = $total_Results[num];
while($row = mysql_fetch_array($sql1))
{
$sql2="select distinct column1 from table2 where column2='".$row['id']."' and left(date,10) BETWEEN '".$datefrom."' AND '".$dateto."'";
$res=mysql_query($sql2);
}
sql1 to get names and sql2 to get Impressions, I need to sort names by Impressions
name | Impressions DESC
A | 10
B | 8
C | 7
or
name | Impressions ASC
C | 7
B | 8
A | 10
Thanks for your attention
I'll add almost the same answer as on your previous question. You can do it all in a join instead of separate queries;
SELECT t1.id as name, COUNT(DISTINCT t2.column1) Impressions
FROM table1 t1
LEFT JOIN table2 t2
ON t1.id=t2.column2
WHERE t1.column1 = 1
AND LEFT(date,10) BETWEEN '2013-01-01' AND '2013-12-31'
GROUP BY t1.id
ORDER BY Impressions DESC
An SQLfiddle to test with.
You need to select id too in your sql1 query
$sql1 = "SELECT id,COUNT(*) as num FROM table1 where column1='1'";
otherwise you won't get id in the result or you can select all the fields + count (*)
$sql1 = "SELECT *,COUNT(*) as num FROM table1 where column1='1'";

How do I join 4 tables on mysql select statement?

I have 4 tables in MySQL to join. Example
$select = $db->query("SELECT *
FROM ads
WHERE ad_pic='1'
AND ad_status = '1'
ORDER BY ad_id DESC LIMIT 0,4");
while ($fetch = $db->fetch($select)) {
$iquery = $db->query("SELECT *
FROM images
WHERE img_ads_id = '" . intval($fetch['ad_id']) . "'
AND img_status = '1'
LIMIT 1");
$thumb = $db->fetch($iquery);
$uselect = $db->query("SELECT *
FROM users
WHERE user_id = '".intval($fetch['ad_userid'])."'
AND user_status = '1'
LIMIT 1");
$ufetch = $db->fetch($uselect);
$cselect = $db->query("SELECT *
FROM category
WHERE cat_slug = '".safe_func($fetch['ad_category'])."'
LIMIT 1");
$cfetch = $db->fetch($cselect);
}
I want to know the way to join these in one select statement.
ads table
ad_id ad_userid ad_category
-------------------------------
1 2 5
images table
img_id img_ads_id
-------------------------------
1 1
users table
user_id user_name
-------------------------------
2 John
category table
cat_id cat_name
-------------------------------
5 Vehicles
SELECT *
FROM ads AS a
LEFT JOIN images AS i ON i.img_ads_id = a.ad_id AND i.img_status = 1
LEFT JOIN users AS u ON u.id = a.ad_userid AND u.user_status = 1
LEFT JOIN category AS c ON c.cat_slug = a.ad_category
WHERE a.ad_pic = 1
AND a.ad_status = 1
ORDER BY a.ad_id DESC
LIMIT 0,4
If an ad must have an image, user, or category, you may use a JOIN instead of a LEFT JOIN. If an ad can have more than one image, user, or category, you will need a more complex query.

A somewhat complex mysql query

I'm currently working on a news database website and I can't seem to create a query to select the 5 hottest news articles. The 2 tables of the database that are affected for this query are:
News - containing all news items (id, author, message, etc.)
Rates - containing all ratings on news items (id, news_id, rating, etc.)
Now my query should select 5 news_ids from the table Rates with the highest average rating and most votes ( so: ordered by AVG(Rating) and COUNT(*) I supposed ). I first tried to make my query as well get all info of these news_ids from the News table instantly ( using a WHERE id IN(--the query selecting the 5 hottest news_ids--) clause ) but that returned an error of my MySql Version not being cappable of using LIMIT inside of the WHERE IN clause sub-query.
Well, I hope you can help me out on the first query that has to select those 5 news_ids. The query I got as for now ( but not fully working ) is:
SELECT news_id FROM
(SELECT news_id, AVG(rating) AS average_r, COUNT(*) AS amt_r
FROM rates
GROUP BY news_id
ORDER BY average_r,amt_r
DESC LIMIT 5
) AS news_rates
or in content with the rest of my script:
$get_hot_news_ids = mysql_query("SELECT news_id FROM
(SELECT news_id, AVG(rating) AS average_r, COUNT(*) AS amt_r
FROM rates
GROUP BY news_id
ORDER BY average_r,amt_r DESC LIMIT 5) AS news_rates");
$first = 1;
while($news_id = mysql_fetch_assoc($get_hot_news_ids)) {
if(!$first) {
$hot_news_ids .= " ,";
}else{
$first = 0;
}
$hot_news_ids .= $news_id['news_id'];
}
//print_r($hot_news_ids);
$get_hot_news = mysql_query("SELECT * FROM news
WHERE id IN($hot_news_ids)
ORDER BY FIELD(id, $hot_news_ids)");
Are you sure both average_r and amt_r are both in descending order?
SELECT news_id FROM
(SELECT news_id, AVG(rating) AS average_r, COUNT(*) AS amt_r
FROM rates
GROUP BY news_id
ORDER BY average_r DESC, amt_r DESC
LIMIT 5
) AS news_rates
Try this:
SELECT TOP 5 N.id, N.author, N.message, AVG(R.rating) AS rate, COUNT(R.news_id) AS votes
FROM news N
INNER JOIN rates R ON N.id = R.news_id
GROUP BY N.id, N.author, N.message
ORDER BY rate, votes
You can use a join instead, which will allow the limit:
SELECT *
FROM news n JOIN (
SELECT news_id, AVG(rating) AS average_r, COUNT(*) AS amt_r
FROM rates
GROUP BY news_id
ORDER BY average_r,amt_r DESC
LIMIT 5
) top5 ON n.news_id = top5.news_id
ORDER BY top5.average_r,top5.amt_r
Note: You might want to change your query to a ORDER BY average_r DESC, amt_r DESC to get the highest rated items, instead of the lowest rated.

Categories