How do I use two mysql tables in one statement - php

So, I've put in a favourite images table, and I can't figure out how to get it working properly
Basically, this is the setup:
ImageFavs
FavID, UserID, ImgID
ImageList
ImgID, SiteID
I'd like it to select 20 or so images from the favourites table, but only ones that match the siteid in the image list table
This is the code I have at the moment, but it dawned on me it'd select 20 images from favourites, then only display them if the matching site was actually checked.
#select matching sites
for($i=0;$i<count($sites)-1;$i++){
$siteinfo = explode("-",$sites[$i]);
$siteid = $siteinfo[0];
$sitegroup = $siteinfo[1];
$selection[$siteid]="exists";
if($i!=0){
$sqlextra .= " OR ";
}
else{
$sqlextra = "AND (";
}
$sqlextra .= "SiteID='".$siteid."'";
}
if(!empty($sqlextra)){
$sqlextra .= ")";
}
else{
$sqlextra = "AND SiteID='-1'";
}
#show favourites
if($_GET['f']==1){
$sql="SELECT * FROM ImageFavs WHERE UserID='".$_SESSION['User_ID']."' AND Active = '1' ORDER BY RAND() LIMIT 20";
#(rand is just me being lazy, eventually I'll figure out how to separate it onto pages)
$result = mysql_query($sql);
$num = mysql_numrows($result);
if($num>0){
while ($row=mysql_fetch_array($result, MYSQL_BOTH)){
if(empty($sqlextra2)){
$sqlextra2 = " AND (";
}
else{
$sqlextra2 .= " OR ";
}
$sqlextra2 .= "ImgID='".$row['ImgID']."'";
}
$sqlextra2 .= ")";
}
}
#don't show favourites
if(empty($sqlextra2)){
$sqlextra2 = " ORDER BY RAND() LIMIT 20";
}
$sql="SELECT * FROM ImageList WHERE Valid='1' ".$sqlextra.$sqlextra2;
This output $sql from this seems like it could be so much neater though, an example of it is like this
SELECT * FROM ImageList WHERE Valid='1' AND (SiteID='6') AND (ImgID='5634' OR ImgID='8229' OR ImgID='9093' OR ImgID='5727' OR ImgID='7361' OR ImgID='5607' OR ImgID='7131' OR ImgID='5785' OR ImgID='7339' OR ImgID='5849' OR ImgID='7312' OR ImgID='5641' OR ImgID='8921' OR ImgID='7516' OR ImgID='7284' OR ImgID='5873' OR ImgID='8905' OR ImgID='7349' OR ImgID='7392' OR ImgID='8725')
Also, while I'm here, would there be a non resource heavy way to count the number of favourites for a user per website?
It's not for anything big, just messing around on a personal website to see what I can do.

You can INNER JOIN your two tables to get the results you want. INNER is used when you want results from both tables. It's best to use aliases to keep your tables straight.
SELECT l.*
FROM ImageFavs f
INNER JOIN ImageList l ON f.ImgID = l.ImgID
WHERE l.SiteID = [your site ID]
AND f.UserID='" . $_SESSION['User_ID'] . "'
AND f.Active = '1'
ORDER BY RAND() LIMIT 20
To get a count by site you can use GROUP BY. I think this should get you that count
SELECT COUNT(f.ImgID)
FROM ImageFavs f
INNER JOIN ImageList l ON f.ImgID = l.ImgID
WHERE f.UserID='" . $_SESSION['User_ID'] . "'
AND f.Active = '1'
GROUP BY l.SiteID

you want to use "JOIN"
SELECT * FROM ImageFavs LEFT JOIN ImageList ON ImageFavs.ImgID = ImageList.ImgID WHERE ImageList.SiteID = <your_site_id>

This works-
//Assuming $site_id contains the site ID/
$query = "select *.IF from ImageFavs as IF, ImageList as IL where IL.ImgId = IF.ImgId and IL.SiteId = $site_id LIMIT 20"

Related

select down and up votes for each post php mysql

I have a forum where users can post questions and can upvote and downvote.
I want to get the upvote and downvote of each post.
What i did previously was do that in 3 sets queries.
$data = mysqli_query($con,"select * from posts");
while($row = mysqli_fetch_assoc($data)){
$pid = $row['post_id'];
$up = mysqli_fetch_assoc(mysqli_query("SELECT COUNT(*) as c FROM up WHERE post_id = $pid"))['c'];
$down = mysqli_fetch_assoc(mysqli_query("SELECT COUNT(*) as c FROM down WHERE post_id = $pid"))['c'];
}
Can anyone show me how can i do these things in one single query because if a get a lot of posts in 1st query then there will be lots of queries to do.
You can use subqueries and put everything in the first query.
This could be a good start :
$data = mysqli_query($con, "select posts.*, " .
"(SELECT COUNT(*) FROM up WHERE post_id = posts.post_id) as totalUp, " .
"(SELECT COUNT(*) FROM down WHERE post_id = posts.post_id) as totalDown " .
"from posts");
while($row = mysqli_fetch_assoc($data)){
// ...
}
you can use corelated subquery for this where upvotes
and downvotes are counted based on the post id
SELECT p.*,
( select count(*) from up where post_id = p.post_id ) as upVotesCount,
( select count(*) from down where post_id = p.post_id ) as downVotesCount,
FROM posts p

Looping through a mysqli result

I'm trying to display a list of status updates from artists that a logged in user is following.
So far I have this:
#Get the list of artists that the user has liked
$q = "SELECT * FROM artist_likes WHERE user_id = '1' ";
$r = mysqli_query($dbc,$q);
while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
#Now grab the statuses for each artist
$status_query = "SELECT * FROM status_updates WHERE artist_id = '".$row['artist_id']."' ";
$status_result = mysqli_query($dbc,$status_query)
}
But i'm not sure how to loop through and display the returned status updates?
This isn't a strong point of mine, so any pointers would be greatly appreciated!
What prevented you from doing similar to what you'd already done for the first query? Something like follows:
#Get the list of artists that the user has liked
$q = "SELECT * FROM artist_likes WHERE user_id = '1' ";
$r = mysqli_query($dbc,$q);
while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
#Now grab the statuses for each artist
$status_query = "SELECT * FROM status_updates WHERE artist_id = '".$row['artist_id']."' ";
$status_result = mysqli_query($dbc,$status_query)
while($status_result_row = mysqli_fetch_assoc($status_result)) {
echo $status_result_row['mycol']; // This is where you know better than us
}
}
Or if those two tables artist_likes and status_updates have artist_id in common then you could just use one query with a join. (But don't know if you are asking for that).
Just for avoiding multiple query, you can use one query like this:
SELECT l.*, s.*
from artist_likes l, status_updates s
WHERE
l.artist_id = s.artist_id and
l.user_id = '1'
or
SELECT l.*, s.*
from artist_likes l
JOIN status_updates s on (l.artist_id = s.artist_id)
WHERE
l.user_id = '1'

Duplicates in php while loop

I am getting a bunch of id's from the database - for each id, I want to do a mysql query to get the relating row in another table. This works fine although I also need to get similiar data for the logged in user. With the mysql query I am using - it duplicates the logged in user data according to how many id's it originally pulled. This makes sense although isnt what I want. I dont want duplicate data for the logged in user and I need the data to come from one query so I can order things with the timestamp.
<?php
mysql_select_db($database_runner, $runner);
$query_friends_status = "SELECT DISTINCT rel2 FROM friends WHERE rel1 = '" . $_SESSION ['logged_in_user'] . "'";
$friends_status = mysql_query($query_friends_status, $runner) or die(mysql_error());
$totalRows_friends_status = mysql_num_rows($friends_status);
while($row_friends_status = mysql_fetch_assoc($friends_status))
{
$friends_id = $row_friends_status['rel2'];
mysql_select_db($database_runner, $runner);
$query_activity = "SELECT * FROM activity WHERE user_id = '$friends_id' OR user_id = '" . $_SESSION['logged_in_user'] . "' ORDER BY `timestamp` DESC LIMIT 15";
$activity = mysql_query($query_activity, $runner) or die(mysql_error());
$totalRows_activity = mysql_num_rows($activity);
echo "stuff here";
}
?>
You can try this single query and see if it does what you need
$userID = $_SESSION['logged_in_user'];
"SELECT * FROM activity WHERE user_id IN (
SELECT DISTINCT rel2 FROM friends
WHERE rel1 = '$userID')
OR user_id = '$userID' ORDER BY `timestamp` DESC LIMIT 15";
You probably want something like this:
$user = $_SESSION['logged_in_user'];
  $query_friends_status = "SELECT * FROM friends, activity WHERE activity.user_id = friends.rel2 AND rel1 = '$user' ORDER BY `timestamp` DESC LIMIT 15";
You can replace * with the fields you want but remember to put the table name before the field name like:
table_name.field_name
I hope this helps.
<?php
require_once "connect.php";
$connect = #new mysqli($host, $db_user, $db_password, $db_name);
$result = $connect->query("SELECT p.name, p.user, p.pass, p.pass_date_change,p.email, p.pass_date_email, d.domain_name, d.domain_price, d.domain_end, d.serwer, d.staff, d.positioning, d.media FROM domains d LEFT JOIN persons p
ON d.id_person = p.id AND d.next_staff_id_person != p.id");
if($result->num_rows > 1)
{
while($row = $result->fetch_assoc())
{
echo '<td class="box_small_admin" data-column="Imię i nazwisko"><div class="box_admin">'.$row["name"].'</div></td>';
echo '<td class="box_small_admin" data-column="Domena"><div class="box_admin">'.$row["domain_name"].'</div></td>';
}}
?>

PHP/MySQL Retrieve the last action of each user to make a list

i m developing a dynamic website but i have a problem with a query. I m trying to build a map dynamically by retrieving date from the database. I enclose the db structure:
countries (code, name)
data (user_id, dateaction, container)
users (user_id, country_code)
I want to display a list of the AVG container for each country, but the average value should be calculated from last action of each user and the data should be submitted the current day. In the case of non-value of "container" for any country the value is 0. I tried many queries but i couldnt achieve the target. I attach some of the queries i tried.
$query = "SELECT AVG(data.container), data.user_id, users.country_code ".
"FROM data, users ".
"WHERE data.user_id = users.user_id AND dateaction >= '".date('Y-m-d').' 00:00:00'."' AND date < '".date('Y-m-d').' 23:59:59'."'".
"GROUP BY users.country_code ";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
$cid=$row['country_code'];
$queryy=mysql_query("select * FROM Countries WHERE country_code='$cid'") or die("Error Occured,plz try again1");
$rowy = mysql_fetch_array( $queryy );
$cname=$rowy['country_name'];
echo '<area title="'.strtoupper($cname).'" mc_name="'.strtoupper($cid).'"></area>'; }
Please may you help me to solve this logical problem?
$query = "SELECT a.user_id, ifnull(a.country_code, 0) as country_code, avg(a.container) ".
"FROM data a INNER JOIN ".
"(SELECT data.user_id, max(dateaction) dateaction ".
"FROM data".
"WHERE dateaction >= '".date('Y-m-d').' 00:00:00'."' AND date < '".date('Y-m-d').' 23:59:59'."'".
"GROUP BY data.user_id) b ".
"ON a.user_id = b.user_id and a.date_action = b.date_action ".
"GROUP BY a.user_id, ifnull(a.country_code, 0) "

MYSQL like a join but only need the newest row?

I want to do the following but in one query:
$query = mysql_query("SELECT name FROM tbl_users WHERE category = '1'");
while($row = mysql_fetch_assoc($query))
{
$query2 = mysql_query("SELECT datecreated
FROM tbl_comments
ORDER BY datecreated DESC LIMIT 1");
$row2 = mysql_fetch_assoc($query2);
echo $row['name'] . " > " . $row2['datecreated'] ."<br />";
}
There is a user table and a comments table, I want to display a list of users and the date of the last comment next to them?
Is this possible in a single query?
You can do so using the following SQL:
SELECT name,
(
SELECT datecreated
FROM tbl_comments
WHERE tbl_users.user_id = tbl_comments.user_id
ORDER BY datecreated LIMIT 1
)
FROM tbl_users
WHERE category = '1';
OR using:
SELECT tbl_users.name, MAX(datecreated) AS latestcomment
FROM tbl_users LEFT JOIN tbl_comments ON (tbl_users.user_id = tbl_comments.user_id)
GROUP BY tbl_users.name;

Categories