I have a joined table and it gives all books of my database. And all books are displaying properly. But I need to work it according to search queries entered in form.
this is my query for join.
$rs = mysqli_query($connection,"SELECT DISTINCT bk.title As Title, YEAR(bk.date_released) AS Year, bk.price AS Price, cat.name AS Category, pub.name AS Publisher, aut.name AS Author,co.name AS Cover, cp.count AS Copies
FROM books bk
JOIN (SELECT book_id, COUNT(*) as count FROM copies GROUP BY book_id) cp
ON bk.id = cp.book_id
JOIN category cat
ON cat.id = bk.category_id
JOIN publishers pub
ON pub.id = bk.publisher_id
JOIN books_covers bk_co
ON bk_co.book_id = bk.id
JOIN covers co
ON co.id = bk_co.cover_id
JOIN books_authors bk_aut
ON bk_aut.book_id = bk.id
JOIN authors aut
ON aut.id = bk_aut.author_id
JOIN books_languages bk_lan
ON bk_lan.book_id = bk.id
JOIN languages lan
ON lan.id = bk_lan.lang_id
JOIN books_locations bk_loc
ON bk_loc.book_id = bk.id
JOIN locations loc
ON loc.id = bk_loc.location_id
ORDER BY bk.title ASC
");
$copies = mysqli_query($connection,"SELECT DISTINCT COUNT(copies.book_id) FROM copies INNER JOIN books ON copies.book_id=books.id
");
$dup = mysqli_query($connection,"SELECT book_id, COUNT(*) as count FROM copies GROUP BY book_id");
$rows_copies = mysqli_fetch_array($copies);
$rows = mysqli_fetch_assoc($rs);
$tot_rows = mysqli_num_rows($rs);
And this is my variables of search form
if(!empty($_GET)){
$title = $_GET['title'];
$author = $_GET['author'];
$isbn = $_GET['isbn'];
$language = $_GET['language'];
$publisher = $_GET['publisher'];
$year = $_GET['year'];
$category = $_GET['category'];
}else{
$title = "";
$author = "";
$isbn = "";
$language = "";
$publisher = "";
$year = "";
$category = "";
$language = "";
}
And this is my code for displaying results,
<div class="jumbo">
<?php if($tot_rows > 0){ ?>
<?php do { ?>
<div class="col-md-3">
<span class="product-image">
<img src="<?php echo $rows['Cover'] ?>" class="img-thumbnail product-img" alt="">
</span>
<ul class="iteminfo">
<li><strong>Title: </strong><?php echo $rows['Title'] ?></li>
<li><strong>Category: </strong><?php echo $rows['Category'] ?></li>
<li><strong>Author: </strong><?php echo $rows['Author'] ?></li>
<li><strong>Price: </strong><?php echo $rows['Price']." Rs" ?></li>
<li><strong>Publisher: </strong><?php echo $rows['Publisher'] ?></li>
<li><strong>Copies: </strong><?php echo $rows['Copies'] ?></li>
</ul>
</div>
<?php } while($rows=mysqli_fetch_assoc($rs)); }else{ ?>
<?php echo 'No Results'; }?>
</div>
How I get results only I searched with corresponding search queries. For an example if I search a book called "Romeo Juliet" I need to display that book only
I tried to test the diplay with this code and never succeed
$titlequery = mysqli_query($connection," SELECT * FROM "$rs" WHERE Title = "$title" ");
$rows = mysqli_fetch_assoc($titlequery);
Help me to solve this.
You're trying to execute a subquery, but the $rs variable you are passing in is a resource, not a string. If you set the original query to a variable and pass that in, then it should work:
$sql = "SELECT DISTINCT bk.title As Title, YEAR(bk.date_released) AS Year, bk.price AS Price, cat.name AS Category, pub.name AS Publisher, aut.name AS Author,co.name AS Cover, cp.count AS Copies
FROM books bk
JOIN (SELECT book_id, COUNT(*) as count FROM copies GROUP BY book_id) cp
ON bk.id = cp.book_id
JOIN category cat
ON cat.id = bk.category_id
JOIN publishers pub
ON pub.id = bk.publisher_id
JOIN books_covers bk_co
ON bk_co.book_id = bk.id
JOIN covers co
ON co.id = bk_co.cover_id
JOIN books_authors bk_aut
ON bk_aut.book_id = bk.id
JOIN authors aut
ON aut.id = bk_aut.author_id
JOIN books_languages bk_lan
ON bk_lan.book_id = bk.id
JOIN languages lan
ON lan.id = bk_lan.lang_id
JOIN books_locations bk_loc
ON bk_loc.book_id = bk.id
JOIN locations loc
ON loc.id = bk_loc.location_id
ORDER BY bk.title ASC
";
$rs = mysqli_query($connection, $query);
$titlequery = mysqli_query($connection, " SELECT * FROM ({$query}) WHERE Title = '{$title}'");
Also, watch your quotation marks in SQL queries when you need to use PHP quotation marks as string delimiters. PHP will interpret your string of " SELECT * FROM "$rs" WHERE Title = "$title" " as SELECT * FROM, the $rs resource, WHERE Title =, the $title variable, and , but without any concatenation. You'd need to backslash your SQL quotations, like " SELECT * FROM \"$rs\" WHERE Title = \"$title\" ", so PHP doesn't think you want to end your string.
Related
I have two tables:
'comments'
| id | content | user_id | article_id | parent_id |
'users'
| id | name | photo |
And my queries are:
<?php
$query = mysql_query("SELECT comments.id, comments.content, users.name,
users.photo FROM comments, users WHERE comments.article_id = '".$get_id."'
AND comments.parent_id = 0 AND comments.user_id = users.id");
while($res = mysql_fetch_assoc($query))
{
$id = $res['id'];
$content = $res['content'];
$name = $res['name'];
$photo = $res['photo'];
echo $photo;
echo $name;
echo $content;
$query2 = mysql_query("SELECT comments.id, comments.content, users.name,
users.photo FROM comments, users WHERE comments.article_id = '".$get_id."'
AND comments.parent_id = '".$id."' AND comments.user_id = users.id");
while($res2 = mysql_fetch_assoc($query2))
{
$id2 = $res2['id'];
$content2 = $res2['content'];
$name2 = $res2['name'];
$photo2 = $res2['photo'];
echo $photo2;
echo $name2;
echo $content2;
}
}
?>
It doesn't work properly. It shows 1 parent and 1 child comment in each nest although there are several child comments.
How can I fix and minimize it? Can it be done by using only one query?
Thank you!
JOIN the table on itself.
Change your query to:
SELECT comments.id, comments.content, users.name,
users.photo FROM comments JOIN users ON comments.user_id = users.id JOIN
comments c ON comments.id =
c.parent_id WHERE
comments.article_id = '".$get_id."'
AND comments.parent_id = '".$id."'
You don't need the second query, here's the full code:
<?php
$query = mysql_query("SELECT comments.id, comments.content, users.name,
users.photo FROM comments JOIN users ON comments.user_id = users.id JOIN
comments c ON comments.id =
c.parent_id WHERE
comments.article_id = '".$get_id."'");
while($res = mysql_fetch_assoc($query))
{
$id = $res['id'];
$content = $res['content'];
$name = $res['name'];
$photo = $res['photo'];
echo $photo;
echo $name;
echo $content;
}
?>
Just use a JOIN to fetch the comments and with all the children.
SELECT users.id userID, users.name, users.photo , childrenComments.*,
parentComments.id cpId, parentComments.content cpContent,
parentComments.user_id cpUser_id,parentComments.article_id cpArticleId
FROM users JOIN (SELECT * FROM Comment WHERE id=0) parentComments
ON users.id=parentComments.user_id LEFT JOIN Comment childrenComments
ON parentComments.id=childrenComments.parent_id;
Then you can the loop through the result to print it appropriately. This would be better as you would have to run just a single query.
I am making this post system with like button and count for a social networking site.
My end goal is to loop through these two sets of results together. So that the like counts goes with the individual posts as they loop. The posts and likes are in desc order. Everything matches except I can't get these while fetch results to loop together.
Post loop
<table class="postborder">
<?php
$query1 = "SELECT * FROM tbl_images ORDER BY id DESC";
$result = mysqli_query($connect, $query1);
while($row = mysqli_fetch_array($result)) {
?>
<div id="newpost">
<tr>
<td id="userpost"><?php echo $row['username']; ?> </td>
</tr>
<tr>
<td>
<hr id="hrline">
<img id="newimgpost" src="data:image/jpeg;base64,<?php echo base64_encode($row['name']); ?>" height="500" width="500" class="img-thumnail" />
</td>
<tr>
<td id="textpost">
<?php echo $row['textpost']; ?>
</td>
</tr>
<tr>
<td id="likebutton">
<?php } ?>
</div>
</table>
Like count loop
<?php
//index.php
//session_start();
//SESSION['userid'] = (int)3;
$connect = mysqli_connect("localhost", "root", "", "snazzer");
$query2 = "
SELECT tbl_images.id, tbl_images.textpost,
COUNT(likes.id) as likes,
GROUP_CONCAT(users.name separator '|') as liked
FROM
tbl_images
LEFT JOIN likes
ON likes.postid = tbl_images.id
LEFT JOIN users
ON likes.userid = users.userid
GROUP BY tbl_images.id
ORDER BY id DESC
";
$result2 = mysqli_query($connect, $query2);
if (!$result2) {
printf("Error: %s\n", mysqli_error($connect));
exit();
}
while($row = mysqli_fetch_array($result2))
{
echo '<h3>'.$row["textpost"].'</h3>';
echo '
LIKE';
echo '<p>'.$row["likes"].' People like this</p>';
if(count($row["liked"]))
{
$liked = explode("|", $row["liked"]);
echo '<ul>';
foreach($liked as $like)
{
echo '<li>'.$like.'</li>';
}
echo '</ul>';
}
}
if(isset($_GET["type"], $_GET["id"]))
{
$type = $_GET["type"];
$id = (int)$_GET["id"];
if($type == "postid")
{
$query = "
INSERT INTO likes (userid, postid)
SELECT {$_SESSION['userid']}, {$id} FROM tbl_images
WHERE EXISTS(
SELECT id FROM tbl_images WHERE id = {$id}) AND
NOT EXISTS(
SELECT id FROM likes WHERE userid = {$_SESSION['userid']} AND postid = {$id})
LIMIT 1
";
mysqli_query($connect, $query);
header("location:profile.php");
}
}
?>
I believe you could run two queries together. It's fairly simple; just separate each query with semicolon:
$query = "SELECT * FROM tbl_images ORDER BY id DESC;
SELECT tbl_images.id, tbl_images.textpost, COUNT(likes.id) as likes, GROUP_CONCAT(users.name separator '|') as liked FROM tbl_images LEFT JOIN likes ON likes.postid = tbl_images.id LEFT JOIN users ON likes.userid = users.userid GROUP BY tbl_images.id ORDER BY id DESC";
Or separate the variable by incrementing values, you can read their documentation which explains it here.
$query = "SELECT * FROM tbl_images ORDER BY id DESC";
$query .= "SELECT tbl_images.id, tbl_images.textpost, COUNT(likes.id) as likes, GROUP_CONCAT(users.name separator '|') as liked FROM tbl_images LEFT JOIN likes ON likes.postid = tbl_images.id LEFT JOIN users ON likes.userid = users.userid GROUP BY tbl_images.id ORDER BY id DESC";
Then run your code as you normally would except you change mysqli_query to mysqli_multi_query:
$result = mysqli_multi_query( $connect, $query );
while($row = mysqli_fetch_array( $result )) {
//... code your table here ...//
}
You can also the Object-Oriented method which works pretty well:
$result = $connect->multi_query( $query );
But of course both methods should work fine. Do keep in mind, you may be vulnerable to SQL Injections with mysqli_multi_query. This is PHP's official warning:
Security considerations
The API functions mysqli_query() and mysqli_real_query() do not set a connection flag necessary for activating multi queries in the server. An extra API call is used for multiple statements to reduce the likeliness of accidental SQL injection attacks. An attacker may try to add statements such as ; DROP DATABASE mysql or ; SELECT SLEEP(999). If the attacker succeeds in adding SQL to the statement string but mysqli_multi_query is not used, the server will not execute the second, injected and malicious SQL statement.
Considerations
You could always save both results from your while loop in an array and run them in a foreach loop or have them output individually as $array['key']. Which would be a simple workaround to your queries:
<?php
// first query
$query1 = "SELECT * FROM tbl_images ORDER BY id DESC";
$result = mysqli_query($connect, $query1);
while($row = mysqli_fetch_array($result)) {
$array1[] = $row;
}
// second query
$query2 = "
SELECT tbl_images.id, tbl_images.textpost,
COUNT(likes.id) as likes,
GROUP_CONCAT(users.name separator '|') as liked
FROM
tbl_images
LEFT JOIN likes
ON likes.postid = tbl_images.id
LEFT JOIN users
ON likes.userid = users.userid
GROUP BY tbl_images.id
ORDER BY id DESC
";
$result2 = mysqli_query($connect, $query2);
while($row = mysqli_fetch_array($result2)) {
$array2[] = $row;
}
Once you have those records setup you can now use $array1 and $array2 to setup your table.
To get their keys and setup you can use print_r or var_dump and you will be able to see key => value pairs:
print_r( $array1 );
echo '<br />';
print_r( $array2 );
I have two queries that count the number of data for both "artists" and "groups" in my database. I want to display a message if there is data to display for either artists or groups (or both), and if the data returns 0 for both of them then not to display anything.
I have the following code which doesn't seem to work:
<?php if (($numrowsartists==0)OR($numrowsgroups==0)) {
} else {
echo "There is information to display.";
}
?>
Below are the queries I have:
$query = "SELECT COUNT(*) FROM `Credit_To_Artist` AS c2a
INNER JOIN `Credits` AS cr ON cr.credit_id = c2a.credit_id
INNER JOIN `Artist` AS a ON a.artist_id = c2a.artist_id
WHERE c2a.song_id = $id";
$res = mysql_query($query);
$numrowsartists = mysql_fetch_assoc($res);
$query = "SELECT COUNT(*) FROM `Credit_To_Artist` AS c2a
INNER JOIN `Credits` AS cr ON cr.credit_id = c2a.credit_id
INNER JOIN `Artist_Group` AS ag ON ag.group_id = c2a.group_id
WHERE c2a.song_id = $id
ORDER BY ag.group_name ASC";
$res = mysql_query($query);
$numrowsgroups = mysql_fetch_assoc($res);
Thanks in advance. I'm sure it's probably a super basic fix but I'm still very new to php and would appreciate some help.
You should getthe value frorm the row eg using alias for column name
$query = "SELECT COUNT(*) as num_artists FROM `Credit_To_Artist` AS c2a
INNER JOIN `Credits` AS cr ON cr.credit_id = c2a.credit_id
INNER JOIN `Artist` AS a ON a.artist_id = c2a.artist_id
WHERE c2a.song_id = $id";
$res = mysql_query($query);
$row = mysql_fetch_assoc($res);
$numrowsartists = row['num_artists'];
$query = "SELECT COUNT(*) as num_groups FROM `Credit_To_Artist` AS c2a
INNER JOIN `Credits` AS cr ON cr.credit_id = c2a.credit_id
INNER JOIN `Artist_Group` AS ag ON ag.group_id = c2a.group_id
WHERE c2a.song_id = $id
ORDER BY ag.group_name ASC";
$res = mysql_query($query);
$row = mysql_fetch_assoc($res);
$numrowsgroups = row['num_groups'];
There are several solutions, the easiest being the following:
if($numrowsartists[0]+$numrowsgroups[0] > 0)
However, as people have said, you shouldn't use mysql_* functions anymore.
Assuming the ID is user input, you should really use prepared statements.
Also, you can handle both tests in a single query:
$stmt = $con->mysqli_prepare("SELECT COUNT(1) as `count` FROM `Credit_To_Artist` AS c2a
INNER JOIN `Credits` AS cr ON cr.credit_id = c2a.credit_id
INNER JOIN `Artist` AS a ON a.artist_id = c2a.artist_id
INNER JOIN `Artist_Group` AS ag ON ag.group_id = c2a.group_id
WHERE c2a.song_id = ?");
$stmt->bind_param('i',$id);
$stmt->execute();
if($stmt->get_result()->fetch_array()[0] > 0){
...
}else{
//message that nothing was found
}
I'm starting to learn php. I'm able to extract the list of CD from the SQL query in [in this table][1] but there's another query which contains the Category which is linked via ID in this table.
How do I get all the columns in the same result set using one query?
<?php
include 'database_conn.php';
$sql = "SELECT id, title, year, price FROM table_cd";
$queryresult = mysqli_query($conn, $sql)
or die (mysqli_error($conn));
while($row = mysqli_fetch_assoc($queryresult)) {
$iid = $row['id'];
$title = $row['title'];
$year = $row['year'];
$price = $row['price'];
echo "<div>
$title
</div>\n";
echo $row['year'];
echo $row['price'];
}
?>
editCDForm.php:
<?php
$code = $_GET['itemCode'];
$sql = "SELECT * FROM table_cd WHERE table_category.ID = $code
JOIN table_category ON (table_category.Desc = table_cd.ID)";
?>
What you're looking for is called a JOIN which allows you to merge the rows from two or more tables into the same result set.
You can modify your query as illustrated below, by using a LEFT JOIN of the nmc_cd table and the nmc_category table on the catID column, as the common primary attribute between them, giving you the desired result set...
$sql = "SELECT nmc_cd.CDID, nmc_cd.CDTitle, nmc_cd.CDYear,
nmc_cd.CDPrice, nmc_category.catDesc
FROM nmc_cd
JOIN nmc_category on nmc_cd.catID = nmc_cd.catID";
Here's a nice article that may help you visualize what a JOIN looks like in your SQL.
Syntax for joins:
SELECT * FROM table1
JOIN table2 ON (table2.colunmname = table1.columnname)
use can get the data from both tables when joining them:
$sql = "SELECT FT.CDID, FT.CDTitle, FT.CDYear, FT.CDPrice,
ST.catDesc FROM nmc_cd AS FT LEFT JOIN nmc_category as ST ON
FT.catID=ST.catID";
I have managed to create a JOIN query for three tables and can successfully echo out the results in a echoed table, here is my code:
<?php
$sql="SELECT a.product_id, a.Options_id, b.product_name, b.product_price, c.Options_name, c.Price_diff
FROM ProductOptions a
JOIN Products b ON a.product_id = b.product_id
JOIN Options c ON a.Options_id = c.Options_id
ORDER BY product_name DESC";
$result = mysql_query($sql);
if (!$result)
{
echo "An error occurred ".mysql_error();
exit;
}
echo "<table border=1>\n<tr><th></th><th bgcolor=\"#DFE8EC\">Name</th><th>Flavors & Size</th><th bgcolor=\"#DFE8EC\">Price</th><th>Price Difference</th><th bgcolor=\"#DFE8EC\"></th></tr>\n";
while ($line = mysql_fetch_array($result)) {
$name = $line["product_name"];
$price = $line["product_price"];
$options=$line["Options_name"];
$difference=$line["Price_diff"];
echo "<tr><td></td><td bgcolor=\"#DFE8EC\">$name</td><td>$options</td> <td bgcolor=\"#DFE8EC\">£$price</td><td>£$difference</td><td bgcolor=\"#DFE8EC\"></td></tr>\n";
}
echo "</table>\n";
?>
My table works but it shows duplicate entries for product_name and I do not know how to remove them.
You have to use a GROUP BY clause in your query like this:
$sql = "SELECT a.product_id, a.Options_id, b.product_name, b.product_price, c.Options_name, c.Price_diff
FROM ProductOptions a
JOIN Products b ON a.product_id = b.product_id
JOIN Options c ON a.Options_id = c.Options_id
GROUP BY product_name
ORDER BY product_name DESC";