Mysql select max maximum sum values - php

I have a database which contains some picture data and a linking table. The tables are build-up like this:
---pictures---
picid Lat Lon
1 5 6
2 7 31
3 31 43
4 -3 35
---user2pictures---
picid userid vote
1 1 1
1 2 1
3 1 -1
3 2 1
4 2 -1
The table pictures contains a picture id and some data about the image, the table user2votes contains vote data from the images. Each user is able to vote on images, but they can only vote 1 time, so the vote will be either 1 (like) or -1 (dislike).
I want to select everything from the pictures table from pictures which have the highest number of votes. Pseudoquery which might explain better what I want:
SELECT * FROM pictures WHERE (SELECT MAX(SUM(vote)) FROM user2pictures LIMIT 12
In this example picture 1 would return at the top, picture 3 would follow and picture 4 as the last one. I really don't know how to solve this, some help in the right direction would be very much appreciated!
Thanks!

The answer is to JOIN the tables, SUM the votes, and ORDER high-to-low by the sum of the votes
SELECT pictures.*, SUM(user2pictures.vote) AS VoteTotal
FROM pictures
JOIN user2pictures ON pictures.picid = user2pictures.picid
GROUP BY pictures.picid
ORDER BY VoteTotal DESC
LIMIT 12

try this
select p.`picid`, `Lat`, `Lon` from pictures p
inner join user2pictures u2p
on p.picid = u2p.picid
group by u2p.picid
order by sum(vote) desc
limit 12
DEMO

I'll assume that you also want to show the pictures with no votes. So, you can try this:
select
p.picId, sum(v.vote) as votes
from
pictures as p
left join user2pictures as v on p.picId = v.picId
group by
p.picId
order by
sum(v.vote) desc
limit 12;
The left join is what lets you show the pictures with no votes (the column votes will have the value 0)
Hope this helps

Related

Joining Three Tables

I need help with joining three tables, this image shows the fields and table names.
Extract from database:
voting table
id name closed date votes_up votes_down
4 29192 0 1467441761 32 14
21 14427 0 1467450299 1 0
20 14464 0 1467449751 0 0
14 27345 0 1467447075 0 0
9 27329 0 1467443096 1 0
games table
id id_gamepressure id_gamepressure2 title
256 8228 10759 Yu-Gi-Oh! World Championship 2007
512 2520 9294 Boulder Dash Rocks!
768 10155 12664 SpongeBob vs. The Big One. Beach Party Cook-Off
1024 9587 8484 Nacho Libre
images table
id id_game id_gamepressure filename
30695 10001 173814 10001_deca-sports_11792.jpg
30690 10001 173819 10001_deca-sports_1524.jpg
30692 10001 173817 10001_deca-spoets_3551.jpg
30694 10001 173815 10001_deca-sportss_572.jpg
30693 10001 173816 10001_deca_sports_8866.jpg
30691 10001 113818 10001_deca-sports_9417.jpg
Basically I want to be able to find the most popular games via from the "voting table" using the field "votes_up" then linking matching it with the "games table" and finally with the "images table"
I want to display it in list form, sorted by the highest voted game.
like this:
game title (rating) (image)
Something like this, I dont know the actual table names from your image. Or what fields you want.
SELECT
g.id,
i.id //or whatever fields you want.
FROM
games AS g
INNER JOIN
images AS i
ON
g.id = i.id_game
LEFT JOIN
votes AS v
ON
g.id = v.name
ORDER BY
v.votes_up
DESC
In this case as votes is already a sum you dont have to count them like I was thinking, ( votes would be 1 row per vote, that is what I was thinking )
Id use a left join, but I supose as you want the most up voted game it wouldn't really matter.
make sure the ids are indexs as well as the vote counts or sorting will kill the performance.

" People Who Liked this Also Liked " Query in Mysql PHP

Music table
id | title
1 Rap God
2 Blank Space
3 Bad Blood
4 Speedom
5 Hit 'em up
Like table
u_id | m_id
1 1
1 2
1 4
1 5
2 3
2 4
2 5
3 1
3 5
4 1
4 2
4 5
Now if someone visits music with m_id = 1
Then the output might be like
m_id
5
2
4
To explain this a bit...
As m_id = 1 is liked by users -> {1,3,4} which in turn likes ->{2,4,5} musics. Since m_id=5 is liked by max number of users its first followed by m_id = 2 and m_id = 4.
My Try
I queried the users who liked m_id = 1
SELECT u_id FROM likes WHERE m_id =1
Then i stored in in an array and selected each of their likes and
arranged them in desc order of count.
But it is a very slow and long process is there any way i can do this ?
p.s I have heard of Association Rules and Bayesian theorem can be user to achieve this. But can anyone help me out with an example ?
You can JOIN back on the Like table and do something like this.
SELECT also_like.m_id, COUNT(also_like.m_id)
FROM [like] AS did_like
JOIN [like] AS also_like ON
also_like.u_id = did_like.u_id
AND also_like.m_id != did_like.m_id
WHERE did_like.m_id = 1
GROUP BY also_like.m_id
ORDER BY COUNT(also_like.m_id)
Essentially you are getting a list of users who liked an item then getting a complete list of those user's likes excluding the item they just liked.
You can then add a HAVING clause or LIMIT to filter things down a bit more.
using a subquery ...
SELECT m_id, count(u_id) as Rank FROM `like`
WHERE u_id in
(
SELECT u_id
FROM `like`
WHERE m_id = 1
)
AND m_id <> 1
GROUP BY m_id
ORDER BY Rank DESC
and optionally
LIMIT 0, 10
or how many "alsolikes" you want to display

Need hint with MySQL query from 2 Tables

I need a small hint... I've got 2 Tables.
Table 1 gets data from an external api.
Table 2 is static.
Table 1: data
id name status ratio import_id
1 Test online 3 1
2 Tee online 2 1
3 Test online 1 2
4 Tee online 0.01 2
5 Test offline 4 3
6 Teee online 3 3
7 Teet online 1 3
Table 2: names
id name tag active
1 Test t1 1
2 Tee t2 1
3 Teee t3 0
4 Teet t4 1
I want to have the ID from the table names (to write into another table and execute a cronjob)
Explanation Table 1:
id - AI
name - just the name
status - if the entry is active
ratio - the main select
import_id - every 10 minutes I do import from json (~40 entries)
what i've got:
$result = mysql_query("
SELECT
import_id
FROM
data
ORDER BY id DESC LIMIT 1");
while($raw = mysql_fetch_object($result))
{
$the_id = $raw->import_id;
echo $the_id;
}
Now I've got the ID and try to get the latest entry (import_id) with the highest ratio:
$c_result = mysql_query("
SELECT
name, active, ratio, import_id
FROM
data
WHERE
active = '1' AND import_id = '$the_id'
ORDER BY
ratio DESC LIMIT 1");
while($chosen = mysql_fetch_object($c_result))
{
$the_c = $chosen->name;
echo $the_c;
}
That works flawless.
But it is possible that one of the 40 entries provided by api is not in my table "names" or it is not marked as "active".
But I only want the names.id of
the name with the highest ratio
which is in my table "names"
which is marked as active in "names"
and the data.status is online
which is from the latest import (highest import_id)
and write it to another table.
I thought about a LEFT JOIN but if the names.name is not in the table "names" i just get an empty result.
Have you got a hint in the right direction?
SELECT d.name, active, ratio, import_id
FROM data d
JOIN names n ON d.name = n.name
WHERE import_id = (SELECT import_id
FROM data
ORDER BY id DESC
LIMIT 1)
AND d.status = 'online'
AND n.active = 1
ORDER BY ratio DESC
LIMIT 1
DEMO

Calculate net change in ranking after "update", MYSQL

I have a two MYSQL tables:
Table-1
id catid title user_rating
123 8 title-one 3
321 8 title-two 5
and
Table-2
listing_id title user_rating
123 title-one 3
321 title-two 5
Plus, I have this query that calculates the current rank of each "title" based on "user_rating".
SELECT
MAX(x.rank) AS rank
FROM
(SELECT
a.id,
a.catid,
a.title,
b.listing_id,
#rank:=#rank + 1 AS rank
FROM
`table-1` a
INNER JOIN `table-2` b ON a.id = b.listing_id
CROSS JOIN (SELECT #rank:=0) r
WHERE
catid = '8'
ORDER BY user_rating DESC) x
WHERE
id = 123
Now, my issue: I want to calculate the difference in "ranking" (rank) when I update the "user_rating" value.
Please, note: the "user_rating" value is updated by a php script that allow users to vote for a specific content (range 1 to 5, step 0.5).
What's the best way to get the difference between the "previous rank" and "current rank" after the update?
Thanks in advance to all.

MySQL count and total

I have a table with a number of votes recorded in it, each vote goes against a post. What I want to be able to do is count the total occurances of each vote.
Table looks like this:
vote
-----
1
2
3
1
2
3
4
5
2
2
2
2
...and so on...
How can I count the records, e.g. In that list 1x2, 2x6, 3x2, 4x1 and 5x1 times.
select vote, count(votes) as vt
from t_your_table
group by vote
To get what you want you can use GROUP BY and COUNT:
SELECT vote, COUNT(*) AS cnt
FROM votes
GROUP BY vote
Result:
vote cnt
1 2
2 6
3 2
4 1
5 1
Votes that have zero count will not be represented in this result set. If you want to have these included with a count of zero then you will need to use an OUTER JOIN with a table listing all the possible votes.
SELECT
possible_votes.vote,
COUNT(votes.vote) AS cnt
FROM possible_votes
LEFT JOIN votes ON possible_votes.vote = votes.vote
GROUP BY possible_votes.vote
Result:
vote cnt
1 2
2 6
3 2
4 1
5 1
6 0
Check MySQL manual for GROUP BY combined with COUNT.
SELECT vote, COUNT(*) as total
FROM votes
GROUP BY vote

Categories