I'm really hoping that you can clear things up for me regarding JOIN using php as I'm really struggling to come to terms with how it works.
Basically I have 2 tables, one for premium members and another for fans of these members. So I want to get certain information from the "premium" table where a member ($memberid) is a fan.
Premium = id, name, avatar, town, etc, etc
Fans = fan($memberid), fanee(Premium ID)
So I have this code at the moment:
<?php
$get_connections_sql = "SELECT id, name, avatar, town FROM premium LEFT JOIN fans ON fans.fanee=premium.id WHERE fans.fan=$memberid LIMIT 18";
$get_connections_res = mysqli_query($con, $get_connections_sql);
if(mysqli_affected_rows($con)>0){
while ($connections = mysqli_fetch_assoc($get_connections_res)){
$connectionid = $connections['id'];
$connectionname = $connections['name'];
$connectiontown = $connections['town'];
$connectionavatar = $connections['avatar'];
$connections .= "
<div class=\"connectionHolder\"><img class=\"connection\" src=\"uploads/avatars/pro/$connectionavatar\" /></div>
";
}
}else{
$connections = "
<div class=\"noContent\">There are no connections to be shown</div>
";
}
?>
This is returning the else condition so there must be something wrong with my JOIN row - Can anyone please point me in the right direction.
You've said that the column 'id' is ambiguous, this is because you have two tables referenced in your query both with 'id' columns and MySQL does not know which to choose. You can be specific by adding the table name like this:
SELECT premium.id, ...
Additionally, you'll want mysqli_num_rows() instead of mysqli_affected_rows(). Since your query does not affect any rows (like update, delete, insert), instead it's returning a set of rows.
mysql_num_rows() takes the result of a query as its parameter (in your case $get_connections_res) rather than the connection. To make sure that the result is valid first check the value of $get_connections_res before the if... if it's falsey then there's an error in the query. Use mysqli_error() to report the error.
Related
I am currently working on a school time-table management system wherein the student dashboard, Time-table is displayed according to the current day, but when displaying the data, two duplicates come out of nowhere.
Initially, I joined the tables 'students' and 'timetable' through an 'INNER JOIN', but the problem with it was duplicates being placed simultaneously which was later fixed with 'RIGHT JOIN'.
Now, the duplicates display after the entire table has been printed.
HERE IS THE CODE BELOW:-
<?php
require_once("connection.php");
function information($subject, $time, $day, $teacher){
$element = "
<tr>
<td>$subject</td>
<td>$time</td>
<td>$day</td>
<td>$teacher</td>
</tr>
";
echo $element;
}
function getData(){
global $conn;
$sql = '
SELECT DISTINCT students.roll_no
, students.class_room
, timetable.subject_name
, timetable.time_code
, timetable.day_otw
, timetable.teacher_name
FROM students
RIGHT
JOIN timetable
ON students.class_room = timetable.room_no;
';
$result = mysqli_query($conn, $sql);
$mydate=getdate(date("U"));
if(mysqli_num_rows($result) > 0){
while($row=mysqli_fetch_assoc($result)){
if($mydate['weekday'] == $row['day_otw']){
information($row['subject_name'], $row['time_code'], $row['day_otw'], $row['teacher_name']);
}
}
} else {
echo "
<h1 class=\"check-data\">Sorry, You haven't been assigned a class yet!</h1>
<h3 class=\"ask\">Please contact your teacher/supervisor for more information.</h3>
";
}
}
getData();
?>
SO BASICALLY THE ENTIRE TABLE IS BEING DUPLICATED TWICE.
Outer joining makes no sense here. You neither want students without a timetable entry (LEFT OUTER JOIN), nor timetable entries without students (RIGHT OUTER JOIN). Then you are using DISTINCT because you are fightig duplicates, which is a bad idea, because thus you don't examine where the duplicates stem from. There should be no duplicates in the first place, so probably there is something wrong with the join criteria or data. You should fix this instead of looking for inappropriate workarounds.
Your join criteria is that the student is in the same room as the timetable entry. Why is the student associated a room? Do all the student's classes take place in the same room? In that case, yes, a class room would mean a class and then the tables would be related by the class (room). But if that were the case, you would get no duplicates.
I assume there to be something else to relate students with the timetable. Look for a student ID in the timetable. Something like:
SELECT s.roll_no, s.class_room, t.subject_name, t.time_code, t.day_otw, t.teacher_name
FROM students s
JOIN timetable t ON s.student_id = t.student_id
ORDER BY s.student_id, t.day_otw, t.time_code;
Or maybe there is something like an additional class ID, both student and timetable belong to? (The room in both tables would look strange then, however.) Maybe you don't know the database well enough. If this is the case, ask somebody who does.
From your screen, you only need to display timetable data, so there is no point to link to student table
Please consider using the following instead of your right join
SELECT
timetable.subject_name, timetable.time_code,
timetable.day_otw, timetable.teacher_name
FROM timetable
I have updated my original post based on what I learned from your comments below. It is a much simpler process than I originally thought.
require '../database.php';
$pdo = Database::connect();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM Orders WHERE id = 430";
$q = $pdo->prepare($sql);
$q->execute(array($id));
$data = $q->fetch(PDO::FETCH_ASSOC);
echo 'Order Num: ' . $data['id'] . '<br>';
$sql = "SELECT * FROM Order_items
JOIN Parts ON Parts.id = Order_Items.part_id
WHERE Order_Items.orders_id = 430";
$q = $pdo->prepare($sql);
$q->execute(array($line_item_id));
$data = $q->fetch(PDO::FETCH_ASSOC);
while ($data = $q->fetch(PDO::FETCH_ASSOC))
{
echo '- ' . $data['part_num'] . $data['qty'] . "<br>";
}
Database::disconnect();
Unfortunately, only my first query is producing results. The second query is producing the following ERROR LOG: "Base table or view not found: 1146 Table 'Order_items' doesn't exist" but I am expecting the following results.
Expected Results from Query 1:
Order Num: 430
Expected Results from Query 2:
- Screws 400
- Plates 35
- Clips 37
- Poles 7
- Zip ties 45
Now that I understand where you are coming from, let's explain a couple of things.
1.PDO and mysqli are two ways of accessing the database; they essentially do the same things, but the notation is different.
2.Arrays are variables with multiple "compartments". Most typical array has the compartments identified by a numerical index, like:
$array[0] = 'OR12345'; //order number
$array[1] = '2017-03-15'; //order date
$array[2] = 23; //id of a person/customer placing the order
etc. But this would require us to remember which number index means what. So in PHP there are associative arrays, which allow using text strings as indexes, and are used for fetching SQL query results.
3.The statement
$data = $q->fetch(PDO::FETCH_ASSOC)
or
$row = $result->fetch_assoc()
do exactly the same thing: put a record (row) from a query into an array, using field names as indexes. This way it's easy to use the data, because you can use field names (with a little bit around them) for displaying or manipulating the field values.
4.The
while ($row = $result->fetch_assoc())
does two things. It checks if there is a row still to fetch from the query results. and while there is one - it puts it into the array $row for you to use, and repeats (all the stuff between { and }).
So you fetch the row, display the results in whatever form you want, and then loop to fetch another row. If there are no more rows to fetch - the loop ends.
5.You should avoid using commas in the FROM clause in a query. This notation can be used only if the fields joining the tables are obvious (named the same), but it is bad practice anyway. The joins between tables should be specified explicitly. In the first query you want the header only, and there is no additional table needed in your example, so you should have just
SELECT *
FROM Orders
WHERE Orders.Order_ID = 12345
whereas in the second query I understand you have a table Parts, which contains descriptions of various parts that can be ordered? If so, then the second query should have:
SELECT *
FROM Order_items
JOIN Parts ON Parts.ID = Order_Items.Part_ID
WHEERE Order_Items.Order_ID = 12345
If in your Orders table you had a field for the ID of the supplier Supplier_ID, pointing to a Suppliers table, and an ID of the person placing the order Customer_ID, pointing to a Customers table, then the first query would look like this:
SELECT *
FROM Orders
JOIN Suppliers ON Suppliers.ID = Orders.Supplier_ID
JOIN Customers ON Customers.ID = Orders.Customer_ID
WHERE Orders.Order_ID = 12345
Hope this is enough for you to learn further on your own :).
Whilst populating a table based on ids and labels from different tables, it appeared apparent there must potentially be a better way of achieving the same result with less code and a more direct approach using LEFT JOIN but i am puzzled after trying to work out if its actually capable of achieving the desired result.
Am i correct in thinking a LEFT JOIN is usable in this instance?
Referencing two tables against one another where one lists id's related to another table and that other table has the titles allocated for each reference?
I know full well that if theres independent information for each row LEFT JOIN is suitable, but where theres in this case only several ids to reference for many rows, i just am not clicking with how i could get it to work...
The current way i am achieving my desired result in PHP/MySQL
$itemid = $row['item_id'];
$secid = mysql_query(" SELECT * FROM item_groups WHERE item_id='$itemid' ");
while ($secidrow = mysql_fetch_assoc($secid)) {
//echo $secidrow["section_id"]; //testing
$id = $secidrow["section_id"];
$secnameget = mysql_query(" SELECT * FROM items_section_list WHERE item_sec_id='$id' ");
while ($secname = mysql_fetch_assoc($secnameget)) {
echo $secname["section_name"];
}
}
Example of the data
Item groups
:drink
:food
:shelf
Item List
itemId, groupId
Group List
groupId, groupTitle
The idea so outputting data to a table instead of outputting "Item & Id Number, in place of the ID Number the title actually appears.
I have achieved the desired result but i am always interested in seeking better ways to achieve the desired result.
If I've deciphered your code properly, you should be able to use the following query to get both values at the same time.
$itemid = $row['item_id'];
$secid = mysql_query("
SELECT *
FROM item_groups
LEFT JOIN items_section_list
ON items_section_list.item_sec_id = item_groups.section_id
WHERE item_id='$itemid'
");
while ($secidrow = mysql_fetch_assoc($secid)) {
//$id = $secidrow["section_id"];
echo $secidrow["section_name"];
}
In MySQL, how can I select the data of one column, only for the rows where the value of the same row, in another column, is session_id (I want all the values, not only the first one)
I have tried this:
SELECT column_name FROM table_name WHERE ID = $session_id
...but it dosen't work. It only selects the first row.
edit, the code I'm using.
<?php
$dn = mysql_query("SELECT IDcontact FROM contacts WHERE ID = '".$_SESSION['id']."'");
if(mysql_num_rows($dn)>0)
{
$dnn = mysql_fetch_array($dn);
$req = mysql_query("select TitreEvent, DescriptionEvent, MomentEvent, image_small from users_event where Confidentialite = 'Public' and ID = " . $dnn['IDcontact']);
while($dnn = mysql_fetch_array($req))
{
?>
So it takes for exemple, the value of the contact/friend (IDcontact), form the database «contacts», where the ID of the logged user is. What I want is to output the event of all the IDcontact, cause actually, it only output the event of the most recent friend added, witch is... the first row of the «contacts» database.
The mysql_fetch_array() function returns only one row from the query's result set. If you want to get all the rows produced by the query, you have to call it in a loop:
while ($row = mysql_fetch_array($dn)) {
// Do stuff with $row...
}
Also, this function is deprecated. You should instead be using either mysqli or PDO to run your queries. See the PHP documentation on choosing an API for more information.
Since you edited your question to show that you're running a second query based on the results of the first one, note that you can do both the IDcontact lookup and get the users_event info in a single query by joining the two tables:
select TitreEvent, DescriptionEvent, MomentEvent, image_small
from users_event
join contacts
on contacts.IDcontact = users_event.ID
where contacts.ID = $session_id
Last but not least, anytime you insert variables (such as your session_id) into a database query, you need to be mindful of SQL injection. If the session ID comes from a parameter that the user can control (e.g. a browser cookie), an attacker could send a malicious session ID that contains SQL code to run arbitrary queries in your database. For safety, you should first create a prepared statement that has a placeholder where the parameter should go:
... where contacts.ID = ?
and then plug in the session_id variable afterward as a "bind parameter". Both mysqli and PDO provide ways to do this: mysqli_stmt_bind_param and PDOStatement::bindParam.
I'm developing in php/sql a web application where users will be able to post items that they'd like to sell ( kinda like ebay ). I want non-members to be able to comment on the items or ask queries about items.
My problem is I want to display each item as well as any comment/query made about that item, in a similar manner as the way Facebook wall works.
I want to "append comments"(if any) to each item. The comments table is linked to the items table via column item_id. And the items table is linked to users table via column user_id. I have left joined users table with items table to display item details, i tried to left join comments table as well so that there are 3 joined tables.
That fails because no comments are displayed and only one item is displayed, despite there being multiple entries in each table. Here is the code i,m using.
$database->query
('
SELECT sale.*, query.*, users.id AS userid, users.username as user
FROM sale
LEFT JOIN users ON sale.user_id = users.id
LEFT JOIN query on sale.id = query.item_id
where category = "$category" ORDER BY sale.id DESC
');
$show = " "; //variable to hold items and comments
if ($database->count() == 0) {
// Show this message if there are no items
$show .= "<li class='noitems'>There are currently no items to display.</li>" ;
} else {
$show .= "<li>";
while ( $items = $database->statement->fetch(PDO::FETCH_ASSOC) )
{
$show .= "
//show item details in html
";
while( $query = $database->statement->fetch(PDO::FETCH_ASSOC) )
{
$show .= "
//show queries below item details
";
}
$show .= "</li>" ;
}
Welcome to Stackoverflow!
I recommend you taking a look at pdo. If you are already using mysql_ functions, then I recommend you switch. More on that can be found here.
Now that your pointed to the direction of to what functions to use when connecting/running queries, you now should create your tables. I use phpmyadmin for managing my database, I find it very good, but it's up to you what you use. Once you've decided on the service you use to manage your database, you should then learn how to use it by doing some google searches.
Now you need to set up your table and structure it correctly. If you say you're having items, then you should make a table called items. Next create the columns to the properties of the items. Also I recommend reading about Database Normalization, which is a key aspect of setting up your SQL tables Etc.
Once you have everything set up, you've connected to your database successfully Etc. You now need to set up the "Dynamic Page". What I mean by this is, there's only one page, say called 'dynamic', then a variable is passed to the url. These are called GET HTTP requests. Here's an example of what one would look like: http://example.com/item?id=345.
If you've noticed, you'll see the ? then the id variable defined to 345. You can GRAB this variable from the url by accessing the built in PHP array called $_GET[]. You can then type in your variable name you want to fetch into the []'s. Here's an example.
<?php
$data = $_GET['varname']; // get varname from the url
if(isnumeric($data)){ // is it totally made out of numbers?
$query = "SELECT fieldname FROM table WHERE id=:paramname";
$statement = $pdo->prepare($query); // prepare's the query
$statement->execute(array(
'paramname'=>$data // binds the parameter 'paramname' to the $data variable.
));
$result = $statement->fetch(PDO::FETCH_ASSOC); // grabs the result of the query
$result = $result['fieldname'];
echo 'varname was found in the database with the id equal to:'.$data.', and the result being: '.$result;
}
?>
So now you can see how you can grab the variable from the url and dynamically change the content with-in the page from that!
Hope this helped :)