php loop start over when num_rows==0 - php

I'm trying to write a php code to select form tables:
books
images
Some books does not have an image, so I want to skip it and select another book.
I have wrote this code but it does not work with me perfectly.
Now I'm getting only 5 records! it must be 6 as I limited in the book select query.
$slider_sql = "select * from books limit 6";
$slider_result = $conn->query($slider_sql);
while($slider_row = $slider_result->fetch_assoc()) {
extract($slider_row);
$img_sql = "SELECT big_img FROM images WHERE book_id = '$id'";
$img_rs = $conn->query($img_sql);
$img_row = $img_rs->fetch_assoc();
if ($img_rs->num_rows == 0)
continue; //--> here I want to start while again to select another book.
echo $book_name.'<br>';
echo $img_row['big_img'].'<br>';
}
Thanks for your help and time!

Instead of having a sub-query in a loop (which is nearly ALWAYS a bad idea!), use a JOIN instead, which simplifies it to one query instead of two. Then set a condition that big_img should not be empty. This guarantees that you will only find rows where there's an image matching the book. LIMIT will still only ensure the return of 6 rows. <> in MySQL is the same as !=.
$slider_sql = "SELECT b.book_name, i.big_img
FROM books b
JOIN images i
ON i.book_id=b.id
WHERE i.big_img <> ''
LIMIT 6";
$result = $conn->query($slider_sql);
while ($row = $result->fetch_assoc()) {
echo $row['book_name'].'<br>';
echo $row['big_img'].'<br>';
}
MySQL JOIN

Related

How to get specific data from table1, use it in table2

I'm trying to get specific rows in table 1 (stellingen). I want to store these rows to specify the rows im interested in for the second table (stelling). So lets say table 1 has 5 rows where stelling ID matches REGIOID = 5. These IDS from stelling ID I want to use to fetch the data from the second table. see the code to see what I tried. I'm not managing to find a way in order too make this happen.
So maybe too be clearer because people always say im not clear:
There are two tables. they both have a matching column. Im trying to tell the second table I want data but only if it matches the data of the first table. Like a branch of a tree. Then, I want to output some data that's in the second table.
I've tried something like this before:
SELECT
*
FROM
table2
LEFT JOIN
table1 ON
table1.ID = table2.table1_id
I've tried to create a while loop to get the data before(after the first if statement and the last += was for the variable $amountofstellinge):
$amountOfStellinge = 0;
while ($amountOfStellinge<5){
mysqli_data_seek($result, $amountOfStellinge);
Here is the code what it looks like now, its wrong, i've been messing with t a lot, but maybe it shows you what I'm trying to achieve better.
if($result = mysqli_query($con, "SELECT * FROM stellingen WHERE REGIOID=1;")) {
$row = mysqli_fetch_assoc($result);
$stellingid= $row["Stelling_ID"];
//checking.. and the output is obviously not what I want in my next query
printf($stellingid);
//defining the variable
$Timer=0;
$sql1="SELECT * FROM stelling WHERE stelling_iD=$stellingid ORDER BY Timer DESC;";
$records2 = mysqli_query($con, $sql1);
$recordscheck = mysqli_num_rows($records2);
//max 5 data
if ($recordscheck < 5){
while ($stelling = mysqli_fetch_assoc($records2)){
//At the end, i would like to only have the data that is most recent
$Timer = date('d F', strtotime($stelling['Timer']));
echo "<p><div style='color:#ED0887'>".$Timer.":</div><a target = '_blank' style='text-decoration:none' href='".$stelling['Source']."'>".$stelling['Title']."</a></p>";
}}
$recordscheck+=1; } // this is totally wrong
EDIT:
I've tried this, #noobjs
$Timer=0;
$sql1="SELECT
*
FROM
stelling
LEFT JOIN
stellingen
ON
stelling.ID = stellingen.stelling_id
WHERE
stellingen.REGIOID=1
ORDER BY stelling.Timer LIMIT 5 DESC ;";
$records2 = mysqli_query($con, $sql1);
printf($records2);
while ($stelling = mysqli_fetch_assoc($records2)){
$Timer = date('d F', strtotime($stelling['Timer']));
echo "<p><div style='color:#ED0887'>".$Timer.":</div><a target = '_blank' style='text-decoration:none' href='".$stelling['Source']."'>".$stelling['Title']."</a></p>";
}
with this error:
Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in
EDIT for more clarification
Here is some sample data
The expected results is:
every page has uses data from a different REGIOID. I expect the page to show data from the table stelling(Table 1). Accordingly to the REGIOID (Table2)
if i understand right:
SELECT
*
FROM
stelling
LEFT JOIN
stellingen
ON
stelling.stellingID = stellingen.stelling_id
WHERE
stellingen.REGIOID=1
ORDER BY stelling.Timer DESC LIMIT 5 ;

SQL LEFT JOIN without duplicating same row values

I was wondering if someone can help me with my problem that is as follows:
I want to pull once posts.text and uids which belongs to that posts.text but when I execute the code below it does this: eg. there are 4 uids that belongs to the post so I get the posts.text four times instead of once.
$query = mysqli_query($con,
"SELECT posts.text, relationships.uidb
FROM posts
LEFT JOIN relationships
ON posts.uid=relationships.uida
LIMIT 10");
if(mysqli_num_rows($query) > 0){
while($row = mysqli_fetch_assoc($query)){
echo $row['text']." ".$row['uidb']."<br>";
}
}
I would really appreciate any help.
Thanks is advance.
Peter
Update:
Desired output would be like this:
postsArray[0]->text = //post text
postsArray[1]->text = //another post text
postsArray[0]->uids[0] = //approved uid for first post
postsArray[0]->uids[1] = //another approved uid for first post
now it outputs this:
text 10
text 15
text 12
and I want this:
text 10, 15, 12
One way is to use Mysql's GROUP_CONCAT which provides comma separated values list for each group i.e (p.uid)
$query = mysqli_query($con,
"SELECT p.text, GROUP_CONCAT(r.uidb SEPARATOR ', ') uidbs
FROM posts p
LEFT JOIN relationships r
ON p.uid=r.uida
GROUP BY p.uid
LIMIT 10");
if (mysqli_num_rows($query) > 0) {
while ($row = mysqli_fetch_assoc($query)) {
echo $row['text'].' '.$row['uidbs'];
/*$uidbs= explode($row['uidbs'],',');
foreach ($uidbs as $key => $val) {
echo $val.' ';
}*/
echo '</br>';
}
}
GROUP_CONCAT
According to docs The result is truncated to the maximum length that
is given by the group_concat_max_len system variable, which has a
default value of 1024. The value can be set higher, although the
effective maximum length of the return value is constrained by the
value of max_allowed_packet.
Maybe this might work for you:
$query = mysqli_query($con,
"SELECT posts.text, relationships.uidb
FROM posts
LEFT JOIN relationships
ON posts.uid=relationships.uida
GROUP BY posts.uid
LIMIT 10");
if(mysqli_num_rows($query) > 0){
while($row = mysqli_fetch_assoc($query)){
echo $row['text']." ".$row['uidb']."<br>";
}
}
SELECT posts.text, relationships.uidb
FROM posts
LEFT JOIN relationships
ON posts.uid=relationships.uida
GROUP BY posts.primary_key_of_your_post
LIMIT 10
You should call 2 queries. In your first query, call the text, and then call uids.
You should not write complex queries because this will make your business more complex and you will not maintain your code in future.

MySQL select from multiple identical tables and display results randomly with php

Hello I would like to query multiple identical tables in my db which has different prefixes and than display the results randomly but somehow I need to track the origin of the item and I couldn't figure out how
I do the query like this because I don't have access to information_schema
$query = "SHOW TABLES FROM mydb WHERE RIGHT( tables_in_mydb, 5 ) = 'table'";
$res = mysql_query($query);
$num = mysql_num_rows($res);
while($row = mysql_fetch_row($res)) {
$numbers = explode('_', $row[0]);
if($num > 0) {
$q = "SELECT `this`, `that`, `something` FROM ".$numbers[0]."_idetinticaltables"; // :)
$r = mysql_query($q);
while($c = mysql_fetch_array($r)) {
/*display the results randomly with an identifier where the come from*/
}
}
}
You could use ORDER BY RAND() to randomly sort it
The following might work:
Get the list of the tables you're interested in. You already do that.
Create a UNION of multiple SELECT statements. Each SELECT statement differs for the table being selected from and you add a column set to the name of the table (so you can identify it later):
(SELECT *, TABLENAME = 'first_name_of_table' FROM first_name_of_table ...)
UNION
(SELECT *, TABLENAME = 'second_name_of_table' FROM second_name_of_table ...)
UNION
...
ORDER BY RAND() LIMIT 10;
Because it is a UNION you can randomize the whole order then. See How can i optimize MySQL's ORDER BY RAND() function? because it is not that trivial to do well, the example above is only to have an ORDER BY and LIMIT clause placed there. With many entries in your tables, it will kill your server.
$aa=array()
while($c = mysql_fetch_array($r))
{
/*display the results randomly with an identifier where the come from*/
$aa[]=$c;
}
echo $aa; // print "Array"

PHP MySQL select random rows

I have a problem selecting 6 random friends
This is the query I've got so far:
$result = num_rows("SELECT * FROM friends WHERE member_id = '".$_SESSION['userid']."'");
if($result >= 6) {
$f_num = 6;
} else {
$f_num = $result;
}
for($i = 1; $i <= $f_num; $i++) {
$q_get_member_friends = mysql_query("SELECT * FROM friends WHERE member_id = '".$_SESSION['userid']."' ORDER BY rand() LIMIT 1");
$r_get_member_friends = mysql_fetch_array($q_get_member_friends);
echo $r_get_member_friends['friend_with'];
}
I want to select 6 random friends if the logged in user has more or equal to 6 friends
Stuck on this for a while now :/
Thanks for any help :)
If you use:
SELECT *
FROM friends
WHERE member_id = '".$_SESSION['userid']."'
ORDER BY rand()
LIMIT 6
If the person only has 3 friends, the query will only show those three - it doesn't mean that the query will always return six rows.
The best way I've found to select any number of random records is with OFFSET in the query.
Let's say you want 6 random records, so I'll borrow from an answer above and count the total number of friends in the database.
$sql = mysql_query("SELECT COUNT(*) AS total FROM friends WHERE member_id='". $_SESSION['userid'] ."'");
$get_count = mysql_fetch_array($sql); // Fetch the results
$numfriends = $get_count['total']; // We've gotten the total number
Now we'll get the 6 random records out of the total above (hopefully it's > 6),
$query = mysql_query("SELECT * FROM friends WHERE member_id='". $_SESSION['userid'] ."' LIMIT 6 OFFSET " . (rand(0, $numFriends));
while ($rows = mysql_fetch_array($query))
{
/// show your $rows here
}
Using OFFSET may not be the best or most efficient, but it's worked for me on large databases without bogging them down.
Never mind, I figured it out :)
Had to use while not for :'D
First select the number of friends that the user has:
"SELECT COUNT(*) as numFriends FROM friends WHERE member_id='".$_SESSION['userid']."'
...put that into a variable, let's call it "$numFriends"
Then:
for($z=0;$z<6;$z++)
{
$randomFriendIndex = rand(1,$numFriends);
//Get the friend at that index
}
change limit 1 to limit 6 on the eighth line.
Instead of SELECT * at the beginning, try SELECT COUNT(*) and use the actual return value instead of num_rows().
Your loop could generate duplicates. I would suggest trying OMG Ponies answer.
There is a whole chapter about random selection in the book SQL Antipatterns.

Excluding a variable when its value is blank

The code below works great. I have a MySQL database that contains book titles classified in different categories. In the code below, the variable "site" represents a book title. Each category is represented by a different table in the MySQL database.
The code below ranks the top 25 book titles (site) by total votes across all categories (MySQL tables). I am trying to exclude blank book titles (i. e. when site = ''). How can I do this?
I have tried inserting WHERE site != '' in a few places but I get an error message. So I guess I'm asking, where can I insert WHERE site != ''?
Thanks in advance,
John
<?
mysql_connect("mysqlv10", "username", "password") or die(mysql_error());
mysql_select_db("database") or die(mysql_error());
$result = mysql_query("SHOW TABLES");
$tables = array();
while ($row = mysql_fetch_assoc($result)) {
$tables[] = '`'.$row["Tables_in_bookfeather"].'`';
}
$subQuery = "SELECT site, votes_up FROM ".implode(" UNION ALL SELECT site, votes_up FROM ",$tables);
// Create one query that gets the data you need
$sqlStr = "SELECT site, sum(votes_up) sumVotesUp
FROM (
".$subQuery." ) subQuery
GROUP BY site ORDER BY sum(votes_up) DESC LIMIT 25";
$result = mysql_query($sqlStr);
$arr = array();
echo "<table class=\"samples2\">";
while ($row = mysql_fetch_assoc($result)) {
echo '<tr>';
echo '<td class="sitename2">'.$row["site"].'</td>';
echo '<td>'.$row["sumVotesUp"].'</td>';
echo '</tr>';
}
echo "</table>";
?>
You shouldn't have separate tables for each book category. I can't believe you have so many books that any of these tables would grow too large. Any scalability benefits you might gain by splitting the table are offset by the complexity of having to do these UNION queries.
Here's what I'd do:
Unify the tables into one table.
Add a Categories table.
Relate books to categories with a many-to-many table.
Then your SQL query becomes much simpler:
$sqlStr = "SELECT site, votes_up FROM Books
WHERE site IS NOT NULL AND site <> ''
ORDER BY votes_up DESC LIMIT 25";
It's probably safest to put it in the subquery:
$subQueryParts = array();
foreach($tables as $table)
$subQueryParts[] = "SELECT site, votes_up FROM $table WHERE LENGTH(site)";
$subQuery = implode(" UNION ALL ", $subQueryParts);
If possible, you should follow Bill Karwin's advice and store all your books in one table. Dynamic table names are very hard to search and manage, and they do not optimize well.

Categories