Voting SQL conundrum - php

I have a PHP system that allows users to vote photos on a scale of 1 - 5, what I want to do is highlight where two people give each other the same vote/score. I can't figure the SQL out at the moment for my PHP function.
The database looks like this
id, user_uid, voted_uid, score
As someone votes the id is auto incremental, the user_id is inserted from the session uid and the voted_uid comes from the image the user is viewing, then the score is the ranking from 1-5.
In theory we are therefore looking for two similar rows like this:
uid user_uid voted_uid score
7 3 5 3
38 5 3 3
At this point I want my php function to take the current users session and then match their votes and scores with other users.
In the example above I'd have the session id of 3 and I want it to return these two records as matches.

If I understand you correctly, what you want is to find pairs of rows where user_uid of the first row equals voted_uid in the second row and vice versa. But only, if score is the same in both rows.
In that case, this should do the trick:
SELECT a.*
FROM table AS a
JOIN table AS b
ON a.user_uid = b.voted_uid
AND a.voted_uid = b.user_uid
AND a.score = b.score;
If you only want rows that "mention" a specific uid, you of course have to add a WHERE user_uid = 3 OR voted_uid = 3.

Related

Combine 2 columns as 1 with other columns as well

I have this table
myid his_id
7 1
1 7
1 6
1 3
But its giving me 4 records instead of 3, i tried using mysqli "join" , "group by" but didnt work.
Im trying to develop a chat system with pure php and jquery, in d table above, user 7 chatted with user 1 and user 1 chatted with user 7 so i want to see it as just the same chat and the rest of the 2 ( user 1 chatting with user 6 and user 1 chatting with user 3)
I want it to give me just 3 records instead of 4 records, pls any help will be appreciated, thank you
Sorry im not connected to my system, im using a smart phone, forgive my bad formatted query below
$sql = mysqli_query($connectn, "select a.id, b.his_id, a.myid, a.status, a.date_replied FROM chats a JOIN chats b ON b.myid=b.myid WHERE b.his_id='$regestered_id' or b.myid='$regestered_id' GROUP BY b.his_id ORDER BY a.id DESC") ;
If you want distinct combinations of myid and his_id, you must not print id, date_replied, status, etc, but just two columns- his_id, myid.
Because if there are multiple rows with two columns with same values, it is yet another to decide which row must be selected in order to print id, status, etc.
So, just to print which two users are chatting, use myid and his_id. You can later use them for any other information.
Now, the code you wanted is-
$sql = mysqli_query($connectn, "select distinct
least(myid, his_id), greatest(myid, his_id)
from chats");
And yes, like #iblamefish mentioned, don't forget to protect your code against SQL injection.

Count how many rows it takes to reach certain query

I have a pretty simple query,
$query3 = $db->query("SELECT * FROM mybb_ranks WHERE id='1' ORDER by points DESC");
And what it'll return is a database of people who are registered and ranked. Since players points can be randomly changing due to matches, we determine the rank # by assigning it once the value is fetched in a way like this:
$i = 1;
while($row = mysqli_fetch_array($query5))
{
echo "$row[player]'s rank is $i";
$i++;
}
As you can see, it orders the player's by their points, but determines the rank # from a variable that adds after displaying every rank. However, in each of the user profiles, I would like to display their rank as well. This is a bit more difficult, because I need a certain way to count the amount of rows the query has to go through in order to get to the certain player. So for instance, if PlayerB is ranked at #5, I would need a way to display that on his own profile. For this to happen, I imagine the query would need to be altered to be able to count each individual row (4 rows) before it reaches the certain player on the 5th row. I was wondering, how would I go about this?
Try this:
UPDATE mybb_ranks
LEFT JOIN (
SELECT
player,
#rank:=#rank+1 as current_rank
FROM mybb_ranks
WHERE id='1'
ORDER BY points DESC
) AS t
ON mybb_ranks.player = t.player
SET mybb_ranks.rank = t.current_rank
That means you have to create additional column rank in your mybb_ranks table.
This query will update the rank of user each time you generate your ranks list.
So when you need to show user's rank in his profile page you just request it from the table:
SELECT rank
FROM mybb_ranks
WHERE player = :player_id
if you want it more dynamic, you can run this UPDATE query every time when you generate your player profile page, right before SELECT rank.

Select from database with count and count based conditions?

I have a table with data relating to a user, and two important columns:
refer_count, which is updated when a new entry is made in the table with the referred_by column set to that users user_id, and referred_by which is the user_id of the of the user that referred them.
I want to select the users from the table that have the highest number of referrals after a certain date.
For example:
If there are 3 users, one of which referred the other 2 (lets say users 2 and 3), however user 2 was referred on the 2/12/14, whereas user 3 was referred on the 3/1/15.
If the cutoff is 1/12/14, then user 1 is returned with refer_count set to 2, but if the cutoff is after 2/12/14, then user 1 is returned with refer_count set to 1.
I've been thinking of how to do this, but I can't think of a way that would work. Is there a way?
This is via MySQL.
EDIT: I think I may need to provide for information.
The date registered (register_date) is used as the refer date. I need the refer_count to be updated with the number of users referred after the cutoff, however I need to get the actual user. This is for a 'top referrers' table. I can't figure out why I'm having so much trouble thinking of a way to do this.
SELECT user_id FROM usertable WHERE (referal_date BETWEEN '2014-12-2' AND CURDATE())ORDER BY refer_count DESC;
That's the rough idea.
You should look into normalizing your tables if you're keeping that all in the same table, though. It'd be better to keep referals in a seperate table.
Get the row with the maximum in refer_count with a Date condition for your referal_date such that it's after the certainDate:
SELECT user_id FROM table WHERE refer_count = (SELECT MAX(refer_count) FROM table) AND referal_date>certainDate;
Note that WHERE is before SELECT so it will not get the highest count first, but will filter with the date condition then get the highest count.
Edit: Updated query based on edited question.

How do I check for logged in user id and return that row first in a MySQL query?

The query below selects the 'loves' on an item. (think of it as similar to facebooks 'like' system.
There are two tables in use in this select. A link table (containing itemid, userid, lovetime) and this is joined to a users table in order to retrieve the username/user profile url etc.
$lovequery = "select love.lovetime, love.userid as ID, love_users.display_name, love_users.user_url
from ".$wpdb->prefix."comment_loves love
left join ".$wpdb->prefix."users love_users on love_users.ID=love.userid
where commentid = $itemid
order by love.lovetime desc
limit 4
";
The results are limited to 4 because I simply do not need any more data. The total count is stored separately in the actual item table to reduce queries.
Once the rows are retrieved from this query I iterate through the array, cross referencing against the total 'lovecount' and build a text string formatted like so:
You, John Smith, Joe Bloggs and 4 others love this.
This works fine however it fails if the logged in user (YOU) does not have the most recent 'lovetime'
What I want to do is have the currently logged in use always at the top of the returned results even if his/her 'lovetime' is older than the 4 most recent ones so that the string always begins with 'You' if the logged in user has 'loved' this item.
The logged in user id is available in the script as $userid.
To clarify
if I have the following table (the timestamps are written as simple UK dates for legibility purposes):-
userid commentid lovetime
34 3 02/10/2011
24 3 03/10/2011
13 3 06/10/2011
65 3 14/10/2011
1* 3 10/09/2011
* with userid 1 being the logged in user id
I would only get user id's 34,24,13,65 returned in that order due to ordering by 'lovetime'
What I want is for the results to return ideally 1,34,24,65. if that proves too tricky then getting 5 total rows when the userid exists would be okay also.
I hope this is clear enough, it was rather difficult to articulate.
How would I go about modifying the query to ensure the results are as described.
Many thanks.
You can order result by condition like ORDER BY (ID = "auth_user_id") DESC

Php/Mysql Simple survey

I want to make a little php poll. The script should ask the users a question they can only answer by numbers from 0-999. After pressing the submit button the data should be stored into mysql. So I just want to know how much users choosed the same number (in percent). It's a simple poll but I don't want any output to be shown.
You need to use COUNT and GROUP BY:
SELECT
number,
COUNT(number) * 100 / (SELECT COUNT(*) FROM table1) AS percent
FROM table1
GROUP BY number
ORDER BY COUNT(number) DESC
Results:
number percent
2 50.0000
3 30.0000
1 20.0000
Test data:
CREATE TABLE table1 (number INT NOT NULL);
INSERT INTO table1 (number) VALUES (1),(1),(2),(2),(2),(2),(2),(3),(3),(3);
here you go: http://code.tutsplus.com/articles/creating-a-web-poll-with-php--net-14257
It's simple tutorial how to make poll.
YOu can use http://www.phpkobo.com/ajax_poll.php if you need something done..

Categories