How to make MySQL select a random winner when using INNER JOIN - php

SELECT * FROM `surveys` INNER JOIN `surveyusers` ON `surveyusers`.`survID` = `surveys`.`survID` WHERE `surveyusers`.`hasWon` = 0 ORDER BY RAND();
UPDATE surveys SET winner = email;
This was a school assignment that required us to select and update the survey winner.
I use PHP to manage and show surveys, I want the SQL to pick the winner. PHP sets survID
I want to pick a random winner and set the winner coloumn in surveys table to the email in the surveyusers table. But I really have a lot of trouble with it.

Updates can take the same syntax as a Select.
You can combine these two queries into one.
UPDATE `surveys` `s` SET `s`.`winner` = (
SELECT email FROM `surveyusers`
WHERE `surveyusers`.`hasWon` = 0
AND `survID` = 1
ORDER BY RAND()
LIMIT 1
) WHERE `survID` = 1;
The survID you would have to set from PHP of course.

You can nest a SELECT query within your UPDATE query:
UPDATE surveys SET winner = (
SELECT `surveyusers`.email FROM `surveys`
INNER JOIN `surveyusers` ON `surveyusers`.`survID` = `surveys`.`survID`
WHERE `surveyusers`.`hasWon` = 0 ORDER BY RAND() LIMIT 1
) WHERE `survID` = xxx
where xxx is the survey to update.

Related

What join to use

I have two tables, one for registered users and one to store votes.
We are logging in with registrants.id and registrants.zipcode. Once they vote their votes are inserted into the votes table, along with their Registration ID.
Im trying to right a select statement that returns a record that will select all the records for Matched ID and Zipcode, but the ID is not in the Votes.voter column. i have tried all kinds of variations of all the joins i can think of. is it something simple i am missing.
SELECT * FROM registrants
LEFT JOIN votes on registrants.id = votes.voter
WHERE registrants.id = 1 AND registrants.zipcode = 46706 and votes.voter <> 1
Perhaps a not exists query:
select * from registrants
where registrants.zipcode = '46706'
and not exists (select 1 from votes where registrants.id = votes.voter)

Get data from two tables

I have a query regarding join . Basically there are two tables product and product_boost . The table product_boost has the product_id as foreign key which is also in product table .
I want to get the data using join which is available in both the tables, and if not only data from first table will come.
I am using right outer join, here is my query
SELECT * FROM `vefinder_product`
RIGHT OUTER JOIN `vefinder_product_boost` ON `vefinder_product_boost`.`product_id`=`vefinder_product`.`product_id`
WHERE `vefinder_product`.`status` = 1
AND `vefinder_product`.`post_type` != 5
AND `vefinder_product`.`country` IN('348')
AND `vefinder_product`.`product_stock` >0
AND `vefinder_product`.`product_in_stock` = 1
AND `vefinder_product_boost`.`target_age_from` >= 20
AND `vefinder_product_boost`.`target_age_to` <= 40
ORDER BY `vefinder_product`.`is_boosted` DESC,
`vefinder_product`.`is_sponsered` DESC,
`vefinder_product`.`created_date` DESC LIMIT 21
How can i achive the desired thing , because this is not working. I am using codeigniter php.
Use Left join instead, if you want to get all the data from first (leftmost) table.
Any Where conditions on tables other than the first table (leftmost), should be shifted to ON condition in Left Join. Otherwise, Where would filter out unmatched rows also (null in the right side tables).
Try the following instead:
SELECT *
FROM `vefinder_product`
LEFT OUTER JOIN `vefinder_product_boost`
ON `vefinder_product_boost`.`product_id`=`vefinder_product`.`product_id` AND
`vefinder_product_boost`.`target_age_from` >= 20 AND
`vefinder_product_boost`.`target_age_to` <= 40
WHERE `vefinder_product`.`status` = 1 AND
`vefinder_product`.`post_type` != 5 AND
`vefinder_product`.`country` IN('348') AND
`vefinder_product`.`product_stock` >0 AND
`vefinder_product`.`product_in_stock` = 1
ORDER BY `vefinder_product`.`is_boosted` DESC,
`vefinder_product`.`is_sponsered` DESC,
`vefinder_product`.`created_date` DESC
LIMIT 21
Use left join and put where condition in ON cluase
SELECT * FROM `vefinder_product`
left OUTER JOIN `vefinder_product_boost` ON `vefinder_product_boost`.`product_id`=`vefinder_product`.`product_id`
and `vefinder_product`.`status` = 1
AND `vefinder_product`.`post_type` != 5
AND `vefinder_product`.`country` IN('348')
AND `vefinder_product`.`product_stock` >0
AND `vefinder_product`.`product_in_stock` = 1
AND `vefinder_product_boost`.`target_age_from` >= 20
AND `vefinder_product_boost`.`target_age_to` <= 40
ORDER BY `vefinder_product`.`is_boosted` DESC,
`vefinder_product`.`is_sponsered` DESC,
`vefinder_product`.`created_date` DESC LIMIT 21
you can use third party software like SQLyog.
it is very simple for join query just build query with UI and assign relation to that fields between tables.
in sqlyog you can get data from multiple tables not only two tables.
because i am currently using this software for time saving.

SQL command to get the count from an average (ie what is n)

Two tables:
1. stories, one column lists over 10,000 story titles with other columns including author, date, category etc. 'id'is the column that is a unique identifyer (auto incrememnting for each story)
2. ratings. This table records star ranking for each of the stories. So this table, has 3 columns, a auto incrementing unique id, the id from table number 1 (which in table 2 is called storyidr)/, the rank value.
So i would like to report the average rating and the total number of ratings for each story.
I've used sql JOIN and I can get the average rating to report fine.
SELECT s.*,
ROUND(AVG(r.rank),0)
AS avrank
FROM stories s
LEFT JOIN ratings
AS r
ON r.storyidr = s.id
GROUP BY s.id
ORDER BY RAND()
LIMIT 200;";
Getting the count is another story. i'm trying COUNT and UNION. Nothing is working. Is there a way to 'extract' the 'value of n' from the average value that is already being queried?
knowing that average=(sum/n)
I don't have to do it this way. If i could add additional SQL queries to the current one to get the count that would be just fine. I'm just not seeing how to add the count function to the current script?
With suggestions:
$query="SELECT s.*, COUNT(r.rank) AS rkct ROUND(AVG(r.rank),0) AS avrank FROM stories s LEFT JOIN ratings AS r ON r.storyidr = s.id GROUP BY s.id ORDER BY RAND() LIMIT 5;";$result=mysqli_query($connection,$query);
<?php while ($data = mysqli_fetch_assoc($result)):$id = $data['id'];$author = $data['author'];$email = $data['email'];$title = $data['title'];$img_link = $data['img_link'];$smaller_img = $data['smaller_img'];$story_link = $data['story_link'];$page_path = $data['page_path'];$tag_alt = $data['tag_alt'];$category = $data['category'];$avgrate = $data['avrank'];$rankcount = $data['rkct'];
The suggestions are giving me the same error: Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in intro.php on line 88.
this is line 88: $avgratep = "Avg rating: " . $avgrate . "/5";
seems like adding the count is making the avrank value nothing or non-numeric?
Just call the count function in the same way you call avg:
SELECT s.*,
ROUND(AVG(r.rank),0) AS avrank,
COUNT(*) AS countrank
FROM stories s
LEFT JOIN ratings
AS r
ON r.storyidr = s.id
GROUP BY s.id
ORDER BY RAND()
LIMIT 200;

mySQL: Sub SELECT statement within UPDATE command

I'm trying to update a column in visitors. I'm also using a sub select statement for the SET part of the update query.
UPDATE
visitors AS v
SET
v.IsFirstVisit = (SELECT COUNT(*) FROM visitors AS v2 WHERE ..... LIMIT 1)
However, mySQL returns this error message
#1093 - You can't specify target table 'v' for update in FROM clause
I have no clue why I can't access the 'v' object within the inner select statement. I also don't want to use multiple statements as this would cause a performance issue.
Question: How can I use the 'v' object within the inner select?
Update:
This is the entire query
UPDATE
visitors AS v
SET
IsFirstVisit = (SELECT Count(*) FROM visitors AS v2 WHERE v2.VisitorId < v.VisitorId AND v2.IP = v.IP AND v2.DateTime > v.DateTime [TODO:SUBTRACT30MINUTES] LIMIT 1)
WHERE
VisitorId = "991"
i guess you looking for this
UPDATE
visitors
SET
IsFirstVisit = (SELECT COUNT(*) FROM visitors WHERE ..... LIMIT 1)
edit:
try this
UPDATE
visitors
SET
IsFirstVisit = (SELECT Count(*) FROM visitors v2 inner join visitors v
ON v.VisitorId = v2.VisitorId WHERE v2.IP = v.IP AND v2.DateTime > v.DateTime AND v2.VisitorId < v.VisitorId [TODO:SUBTRACT30MINUTES] LIMIT 1)
WHERE
VisitorId = "991"
The inner join in UPDATE statement won't be a bad idea.
UPDATE
visitors inner join (SELECT COUNT(*) as test FROM visitors v) as v
SET
isfistvisit = v.test;
Another workaround which Im not a big fan of it.
update visitors
set isfistvisit = (
select count(*) from (
select count(*) from visitors
) as x
)
Demo

MySQL - Returning a random record using LEFT JOIN

I am wondering of someone could help me out.
I want to display random 'polls' on my website, I have about 50 in my database and I want to display one different one each time the person reloads the page.
To get the poll, I am using the following SQL query .... But this gets the first one in the table ... how can I tell it to get a random 'poll'
SELECT *
FROM polls
LEFT JOIN pollanswers ON polls.pollID = pollanswers.pollID
WHERE polls.pollID = 1
ORDER By pollAnswerListing ASC
Thanks much
Use ORDER BY RAND() LIMIT 1, and probably remove the WHERE clause, assuming polls.pollID is your primary key.
SELECT *
FROM polls
LEFT JOIN pollanswers ON polls.pollID = pollanswers.pollID
/*WHERE polls.pollID = 1*/
ORDER BY RAND() LIMIT 1
You have to change the pollID to some random number
polls.pollID = 1
to e.g.
polls.pollID = 9
Generate a Random number between 1 and 50 (assuming you have 50 polls)
and pass that to your mysql query as PollId value instead of the hard coded value 1
var randomId= rand(5, 50);
Use this randomId in your query

Categories