I want to combine data from two MySQL tables and echo results using PHP. The first table is called TEST1 and has two fields(name, info1). The second table is called TEST2 and has also two fields(surname, info2). I would like to select name and surname where info1 = info2 and print name and surname in the same row using PHP. The code I have written so far is this but I don't think it's totally correct for both of the tasks I want it to to do.
$sql = "SELECT name, surname FROM TEST1, TEST2 WHERE info1 = info2";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo " - Name: " . $row["name"]. " - Surname: " . $row["surname"]. "<br>";
}
} else {
echo "0 results";
}
$conn->close();
?>
So for example lets say that TEST1 has at name, info1 [(John,112233),(Luke,112244), (Ariana,112255)] and TEST2 has at surname, info2 [(Lala,112255), (Zara,112233), (Azon,112267), (Esora,112248)]. So I want it to display when I visit the webpage:
Name: John - Surname: Zara
Name: Ariana - Surname: Lala
or
Name: Ariana - Surname: Lala
Name: John - Surname: Zara
name, surname, info1, info2 are VARCHAR(64). There seem to be similar quetions but they aren't easy to understand especially for PHP and MySQL beginners who can't understand more advanced scripts cause they are specific to the asker's problem. So I tried to do it general in order to help more people and not just me. Could you please help me? Thanks in advance.
First of all the info data, if stored this way is becoming redundant and consuming more space in your database. If you have several names and surnames pointing to different persons, you just may take one particular name and surname or their id's in a different table and store the info corresponding to that person there.
Table1 = {tableOneId, firstName}
Table2 = {tableTwoId, lastName}
Table3 = {tableThreeId, tableOneId, tableTwoId, info}
This way you can store variety name and surname only once at a time and the information for each person redundantly. Now join these tables to get the desired information.
Select * from `table1`
inner join `table3` on `table1`.`tableOneId` = `table3`.`tableOneId`
inner join `table2` on `table3`.`tableTwoId` = `table2`.`tableTwoId`
Now you can select the name and surname the way you are doing from the result set.
I would add "tableOneId" (or whatever you like) as foreign key to second table that equals to the Id of the first - which will make it primary key. And as I understand that's the basic principle of relational databases.
So structure:
Table1 = {Id, firstName, info}
Table2 = {Id, lastName, info, tableOneId}
Assuming that firstName and lastName always refers to one unique person and you needed to divide this information to two different tables for some reason, you can implement this strategy to have unique identifier as Id in one table and tableOneId to second, to select unique data for one person from both tables.
And query could be something like this:
Select * from `table1`, `table2` where `table1`.`Id` = `table2`.`tableOneId`;
Related
For a schoolproject we have to make a website that interacts with a myphp database. We want to pull data from two different tables in the database, but when we try to echo the data, only data from the first table is shown.
Out two tables are: TICKET and VISITOR
This is our code:
include 'login.php';
$sql = mysql_query("SELECT * FROM TICKET VISITOR ",$mysql)
or die("The query failed!");
mysql_close($mysql)
or die("Closing the connection failed!");
if (!$sql) {
echo 'Could not run query: ' . mysql_error();
exit;
}
echo "<br/>";
while ($row = mysql_fetch_row($sql)) {
echo $row[0];
echo " ";
echo $row[1];
echo " ";
echo $row[2];
echo "<br/>";
}
basically the comments say it already: you can use joins for this task. However I think what you need is a proper introduction into the options and what it all means, so let me try help you there:
First question: What is your problem? If you want to get data from two tables indepedently then what you have two do is to make to separate queries. You more or less run this:
//first run this query
$sql = mysql_query("SELECT * FROM TICKET ",$mysql)
//Run the query and process the data
//then run this query
$sql = mysql_query("SELECT * FROM VISITOR ",$mysql)
//Process this data, too
What you probably actually want to do is to get data from ONE table based on data from ANOTHER table. For example you want to get some data about users and in one table you have their email address and their street address and in the other table you have their name. So you JOIN both tables together based on some information (key) they both contain. So then you go from
TABLE 1: id | email | address
TABLE 2: id | firstname | lastname
To this form:
NEW TABLE: id | email | address | firstname | lastname
There are different kinds of joins. The code for this could look something link this:
$sql = mysql_query("SELECT table1.id, table1.email, table1.address, table2.firstname, table2.lastname FROM TABLE1 LEFT JOIN TABLE2 ON (table1.id = table2.id)",$mysql)
As said before joins are common and properly explained elsewhere. I find this a good tutorial but of course the mentioned documentation (https://dev.mysql.com/doc/refman/5.7/en/join.html) also explained it maybe a bit more condensed.
Option 1 join
SELECT * FROM TICKET INNER JOIN VISITOR ON NAME;
NAME here is a column name maybe id
Option 2 UNION
SELECT * FROM TICKET UNION SELECT * FROM VISITOR;
As per your code just insert comma (,) after first table. See below -
$sql = mysql_query("SELECT * FROM TICKET, VISITOR ",$mysql)
or die("The query failed!");
Also you can use the inner join if any foreign key used on second table.
Use also union.
I have a table that is being displayed in a form, which looks like this: http://puu.sh/5VBBv.png
The end of the table, City, is displaying an ID of a city, which is supposed to be linked to another table (http://puu.sh/5VBIG.png).
What I've done for my INNER JOIN query is:
mysql_query("SELECT * FROM cities INNER JOIN people ON people.cityid = cities.id") or die(mysql_error());`
and I'm trying to output it into a table:
echo "<td>" . $row['cityid'] . "</td>";
My issue is that I'm not quite sure how to actually display the cityid that corresponds to the city name. I've tried using ['name'] and other values as the value to output in the table, and I can't find any solution for this anywhere so far. I'm just learning joins, so I don't exactly have any knowledge on what I could be doing wrong. Is there anything immensely obvious?
First your use of * in the join query could be ambiguous. If cities had a name column and people had a name column, you won't know which one you're getting. Second you can do this a couple ways. I think you're trying to get a city id from a city name. If that's correct you can either make and ajax call and query it directly or define an array as follow:
$res = mysql_query("...");
$city_ids = Array();
while ($ary = mysql_fetch_assoc($res)) {
city_ids[$ary['name']] = Ary['id'];
}
Then when you get the name, you just loop up $ary['name'].
Selecting from people and joining cities makes more sense. Then select the fields you need.
SELECT people.*, cities.name as city_name FROM people JOIN cities ON people.cityid = cities.id
Then, echo $row['city_name']
Select ID from cities city, people person where person.ID = city.ID
You are selecting the ID from both Cities and People, and joining on the ID
I have a table which holds details of exams taken. Each exam entered into this table is entered as a pair of people i.e. two people per exam performed so you have per exam, two people. Each person has their own unique id for each exam taken but each pair has a value called partner_id which is the same for them both.
What I am trying to do is extract the partner_id values from that table in order to then be able to use those values to find the partners of a said person and show/echo onto the page the exam result details of every partner that person has had exam with.
What I have tried so far is:
$partner_ider = mysql_query("SELECT partner_id as value1 from exam WHERE Student_email='eating#gnomes.com'");
$row1 = mysql_fetch_array($partner_ider);
while($row1 = mysql_fetch_array($partner_ider))
{
echo $row1['value1'];
}
And this:
$result = mysql_query("SELECT * from exam WHERE Student_email='beating#dead.com'");
$row = mysql_fetch_array($result);
while ($row = mysql_fetch_array($result))
{
echo $row['partner_id'];
}
The result these would give is 2 for that email of which has two entries in the exam table, what I was looking for was 1, 2 which are the values of the two partner_ids for this email's exam records. When I change the email to someone else who only has one, it returns nothing.
What I would be looking to do with the result of 1, 2 is to use those values to select all other people except the original person(eating#gnomes.com) and show their details from out of that table.
What I'm asking for is how would I go about doing the above as I haven't done something like this before?
In both code snippets, you have at line 2 a mysql_fetch_array() which should not be there.
It fetches a row, puts it into $row1 and increments the internal pointer.
When you call mysql_fetch_array() in your while, it fetches the second record then the third etc. until all the rows have been processed.
You should, in both examples, remove the second line and try again.
$partner_ider = mysql_query("SELECT partner_id as value1 from exam WHERE Student_email='eating#gnomes.com'");
//$row1 = mysql_fetch_array($partner_ider);
while($row1 = mysql_fetch_array($partner_ider))
{
echo $row1['value1'];
}
If your table structure is the following :
id
student_id
student_name
student_email
student_whatever
partner_id
The SQL query would look like
SELECT Student_email FROM exam WHERE partner_id IN (SELECT partner_id FROM exam WHERE student_Email = 'eating#gnomes.com') AND Student_email <> 'eating#gnomes.com';
But you should really split up your table. You have two entities (a student and an exam) and a joining table.
Student
id
name
email
Exam
id
name
(other exam data)
StudentGroup
exam_id
student_id
group
EDIT: Added the first SQL query.
A section of my website has two dropdown menus. All the options in both are populated using SQL queries. Dropdown#1 is a list of class sections (like A1 for example). Once the professor selects a section, Dropdown#2 is populated with the student ID's (like 1234567 for example).
Student information is found in table 1. Among this information is the 'professorName' column. In order to associate the student with a class section, I need to match 'professorName' column with an identical column found in table 2, because class sections are only found in table 2.
Till here everything works great, because at the end of my query I put ORDER BY student ID. However, two of the class sections are associated to two different professors. In order to deal with this issue, I used the following code to loop through each professor name.
$from site = $_POST['section'];
$query = ("SELECT professorName FROM Table 2 WHERE classSection='$fromsite'");
$NumberofProfessorNames = $objMSSQL->getAffectedRows();
echo $NumberofProfessorNames;
for ($j=0; $j<$NumberofProfessorNames; $j++)
{
$section= $query[$j][professorName];
$output = $objMSSQL->getTable("SELECT DISTINCT StudentID from table1 WHERE professorName='$section' ORDER BY StudentID");
for ($i=0; $i<$objMSSQL->getAffectedRows(); $i++)
{
echo "<option value='".$output[$i][studentID]."'>".$output[$i][studentID]."</option>";
}
}
The problem is that for the only two sections where this is even necessary (because there are two professorNames), since it is looping like this, it is ending up ordered like this in the dropdown#2:
1234567
2345678
3456789
4567890
1234123
2345765
3456999
4567000
My limited experience in programming is keeping me from understanding how I can fix this seemingly simple issue.
Thank you for your help.
Rather than loop over the professors and query table1 for each, join table1 and table2 in the second query and only query the database once. For example:
$query = [... FROM Table2...];
$NumberofProfessorNames = $objMSSQL->getAffectedRows();
echo $NumberofProfessorNames;
$output = $objMSSQL->getTable("
SELECT DISTINCT StudentID
from table1
join table2
on ...
WHERE [the same clause you used in $query]
ORDER BY StudentID"
);
for ($i=0; $i<$objMSSQL->getAffectedRows(); $i++)
{
echo "<option value='".$output[$i][studentID]."'>".$output[$i][studentID]."</option>";
}
It's more elegant (and almost certainly more efficient) than generating a WHERE IN clause.
Yu can do it this way:
$section = "('";
for ($j=0; $j<$NumberofProfessorNames; $j++)
{
$section.= $query[$j][professorName] . "','";
}
$section = substr($section, 0, -3) . ')'; //$section contains ('prof1','prof2')
$output = $objMSSQL->getTable("SELECT DISTINCT StudentID from table1 WHERE professorName IN $section ORDER BY StudentID");
for ($i=0; $i<$objMSSQL->getAffectedRows(); $i++)
{
echo "<option value='".$output[$i][studentID]."'>".$output[$i][studentID]."</option>";
}
that is querying for all your professors in just one sql with IN() syntax.
UPDATE: I've just noted you use sql server instead of mysql, so I've changed the IN() syntax a bit and change the link to the sql server help docs.
It sounds like your tables aren't normalized. Good form would have a sections table, a students table, and a professors table. Information in each table should be specific to the table's topic.
students
student_id
student_last_name
student_first_name
student_address
etc
sections
section_id
section_name - multiple sections can tend to have the same name but differing content
section_description
section_year - sections can change from year to year
faculty
faculty_id
faculty_name - this is not a key field, more than one person can have the same name.
faculty_address
faculty_type - adjunct, fulltime, etc.
You would then have relational tables so you can associate professors with sections and students with sections.
faculty_2_sections
f2s_id
faculty_id
section_id
student_2_sections
s2s_id
student_id
section_id
This makes it super simple because if a student is logged in, then you already have their student id. If it's a professor, you already have their faculty_id
If you're pulling for students, your sql might look like this:
$sql = "select * from students s,sections sc,faculty f,faculty_2_sections f2s,student_2_sections s2s where student_id='$student_id' and s2s.student_id=s.student_id and s2s.section_id=sc.section_id and f2s.faculty_id=f.faculty_id and f2s.section_id=s2s.section_id";
If you're pulling for faculty you would do this:
$sql = "select * from students s,sections sc,faculty f,faculty_2_sections f2s,student_2_sections s2s where faculty_id='$faculty_id' and f2s.faculty_id=f.faculty_id and f2s.section_id=s2s.section_id and s2s.section_id=sc.section_id and s2s.student_id=s.student_id";
You can then pull a list of sections to populate the section_ids pull-down to only show students or faculty for a specific section.
I'm trying to generate a list of events that a user is attending. All I'm trying to do is search through columns and comparing the userid to the names stored in each column using LIKE.
Right now I have two different events stored in my database for testing, each with a unique eventID. The userid i'm signed in with is attending both of these events, however it's only displaying the eventID1 twice instead of eventID1 and eventID2.
The usernames are stored in a column called acceptedInvites separated by "~". So right now it shows "1~2" for the userid's attending. Can I just use %like% to pull these events?
$userid = $_SESSION['userid'];
echo "<h2>My Events</h2>";
$myEvents = mysql_query("select eventID from events where acceptedInvites LIKE '%$userid%' ");
$fetch = mysql_fetch_array($myEvents);
foreach($fetch as $eventsAttending){
echo $eventsAttending['eventID'];
}
My output is just 11 when it should be 12
Change your table setup, into a many-to-many setup (many users can attend one event, and one user can attend many events):
users
- id (pk, ai)
- name
- embarrassing_personal_habits
events
- id (pk, ai)
- location
- start_time
users_to_events
- user_id ]-|
|- Joint pk
- event id ]-|
Now you just use joins:
SELECT u.*
FROM users u
JOIN users_to_events u2e
ON u.id = u2e.id
JOIN events e
ON u2e.event_id = e.id
WHERE u.id = 11
I'm a bit confused by your description, but I think the issue is that mysql_fetch_array just returns one row at a time and your code is currently set up in a way that seems to assume $fetch is filled with an array of all the results. You need to continuously be calling mysql_fetch_array for that to happen.
Instead of
$fetch = mysql_fetch_array($myEvents);
foreach($fetch as $eventsAttending){
echo $eventsAttending['eventID'];
}
You could have
while ($row = mysql_fetch_array($myEvents)) {
echo $row['eventID'];
}
This would cycle through the various rows of events in the table.
Instead of using foreach(), use while() like this:
$myEvents = mysql_query("SELECT `eventID` FROM `events` WHERE `acceptedInvites` LIKE '".$userid."'");
while ($fetch = mysql_fetch_array($myEvents))
{
echo $fetch['eventID'];
}
It will create a loop like foreach() but simpler...
P.S. When you make a MySQL Query, use backticks [ ` ] to ensure that the string is not confused with MySQL functions (LIKE,SELECT, etc.).