Using PHP to get data from multiple database tables - php

I am trying to query five tables. I am able to query one of the tables with
$query = "SELECT * FROM Stats_player WHERE player='$user'";
However, when I try to query another table with
$query = "SELECT * FROM Stats_player, Stats_block WHERE player='$user'";
the website breaks. Here is the code I am using to echo the data on the screen
<?php
if ($result = $mysqli->query($query)) {
echo "<img src=\"https://minotar.net/avatar/{$user}/100\"><h1>{$user}</h1><br/>";
while ($row = $result->fetch_assoc()) {
//variables
$play_time = $row['playtime']/3600;
$play_time = round($play_time, 1);
$xpgained = $row['xpgained'];
$damagetaken = $row['damagetaken'];
$toolsbroken = $row['toolsbroken'];
$itemscrafted = $row['itemscrafted'];
$itemseaten = $row['omnomnom'];
$commandsused = $row['commandsdone'];
$teleports = $row['teleports'];
$itemspickedup = $row['itempickups'];
$itemsdroped = $row['itemdrops'];
$lastseen = date("F j, Y ", strtotime($row['lastjoin']));
//end of variables
echo "<p>Time on Server: {$play_time} HRS</p>";
echo "<p>Last Seen: {$lastseen}";
echo "<p>Commands Used: {$commandsused}";
echo "<p>XP Gained: {$xpgained}";
echo "<p>Blocks broken: {$row['blockID']}"; //this is data from the table Stats_block
}
$result->free();
}
$mysqli->close();
?>
Any ideas on how I might do this?
Table structor of Stats_player:
| counter | player | Playtime |
Stats_block is:
| counter | player | blockID |

$query = "SELECT * FROM Stats_player, Stats_block WHERE player='$user'"
That's very likely wrong. You should use a JOIN operator.
Here, you are just doing a cartesian products of the two tables, that's hardly what you want. And that may overrun your resource (memory etc.) if the tables have a lot of rows.
Something like
$query = "SELECT * FROM Stats_player p, Stats_block b
WHERE p.block_id = b.id AND p.player='$user'"
or
$query = "SELECT * FROM Stats_player p INNER JOIN Stats_block b ON p.block_id = b.id
WHERE p.player='$user'"
or maybe LEFT OUTER JOIN...
The exact query will depend on your schema.

Without seeing the structure of both tables, something like this could work.
SELECT columnList
FROM Stats_player a
LEFT JOIN Stats_block b ON b.player = a.player
WHERE a.player = '$user'

Have you tried something like this:
SELECT
table1.field1, table1.field2, table2.field1, table2.field2
FROM
table1, table2
WHERE
table1.field1 = " " and table2.field1 = " ";

Related

running 2 SQL select statements

I am trying to run 2 SQL Select queries to retrieve data from 2 different tables and then echo the fields from both tables. The code I am trying doesn't seem to work, any help would be appreciated.
$ModelID = $_GET['model_id'];
$result = mysqli_query($con, "SELECT RegNumber, Colour FROM Car WHERE ModelID = '$ModelID'
UNION ALL
SELECT CarModel, CarMake, CostPerDay FROM Model WHERE ModelID = '$ModelID'");
while($row = $result->fetch_assoc())
{
echo $row["CarModel"];
echo $row["CarMake"];
echo $row["CostPerDay"];
echo $row["RegNumber"];
echo " - " .$row["Colour"];
}
You can change request :
SELECT c.RegNumber, c.Colour , m.CarModel, m.CarMake, m.CostPerDay FROM Car c INNER JOIN Model m ON m.ModelID=c.ModelID WHERE c.ModelID = '$ModelID'
try with LEFT JOIN
$result = mysqli_query($con,
"SELECT c.RegNumber, c.Colour, m.CarModel, m.CarMake, m.CostPerDay
FROM Car AS c
LEFT JOIN Model as m ON c.ModelID = m.ModelID
WHERE c.ModelID = '".$ModelID."'"
);

MySQL SELECT to subquery a many-to-many relationship

I have a bilingual dictionary database that I've created, and the tables are set up like so:
lemma (lemmaID, lemma, meaning)
collocate (collocateID, lemmaID, collocate, notes, connection)
collusage (usageID, lemmaID_u, collocateID_u, japanese, english, englishalt)
partofspeech (posID, partofspeech)
postolemma (lemmaID_p, posID_p)
So far, I have a query that returns tables for the results, and it works just how I'd like it to. (It looks like this)
$q = 'SELECT *
FROM lemma, collocates, collusage
WHERE lemma.lemmaID = collocates.lemmaID AND lemma.lemmaID = collusage.lemmaID_u AND collusage.collocateID_u = collocates.collocateID
ORDER BY lemma.lemmaID;';
$result = mysqli_query($con, $q) or die(mysql_error());
if (!$result || mysqli_num_rows($result) == 0) {
echo 'No rows found';
exit;
}
$lastCatID = 0;
while ($row = mysqli_fetch_assoc($result)) {
$reading = $row['reading'];
$headword = $row['lemma'];
$collocate = $row['collocate'];
if (isset($row['notes'])) {
$notes = '&lpar;'.$row['notes'].'&rpar;';
} else {
$notes = $row['notes'];
}
$japanese = $row['japanese'];
$english = $row['english'];
if (isset($row['englishalt'])) {
$englishalt = ', '.$row['englishalt'].'';
} else {
$englishalt = $row['englishalt'];
}
if ($lastCatID != $row['lemmaID']) {
//starting a new category
if ($lastCatID != 0) {
//close up previous table
echo ' </tbody>
</table> </div>';
}
//start a new div
echo '<div class="entry">
<h4>'.$reading.'【'.$headword.'】 <span class="pos">'.$WANT TO LIST PARTS OF SPEECH HERE.'</span></h4>
<table class="table table-striped table-hover">
<tbody>';
$lastCatID = $row['lemmaID'];
}
echo '<tr>
<td><span>'.$collocate.'</span><span class="notes">'.$notes.'</span></td>
<td>'.$japanese.'</td>
<td>'.$english.''.$englishalt.'</td>
</tr>';
}
if ($lastCatID != 0) {
//close up the final table
echo ' </tbody>
</table></div>';
}
mysqli_free_result($result);
What I can't figure out how to do is to use the postolemma junction table to get all of the partofspeech values for each lemmaID so I can list them next to the lemma in the table. Everything SELECT query I have done so far has duplicated collocation entries, which I don't want. Any help is appreciated!
Edit: Here is a link to the SQL Fiddle with data. I couldn't get my foreign key constraints to work so just that is missing.
if I understand you correctly you want to select all values from table partofspeech based on lemma table. Your query should look like this:
SELECT part.partofspeech
FROM partofspeech part
INNER JOIN postolemma post
ON part.posID = post.posID_p
INNER JOIN lemma l
ON post.lemmaID_p = l.lemmaID
Also I would suggest you to change the query you use and start using JOIN operator in syntax, it's good practice and it's not hard to switch from one to another... So your query:
SELECT *
FROM lemma, collocates, collusage
WHERE lemma.lemmaID = collocates.lemmaID
AND lemma.lemmaID = collusage.lemmaID_u
AND collusage.collocateID_u = collocates.collocateID
ORDER BY lemma.lemmaID;
Will look like this:
SELECT *
FROM lemma
INNER JOIN collocates
ON lemma.lemmaID = collocates.lemmaID
INNER JOIN collusage
ON collusage.collocateID_u = collocates.collocateID
AND lemma.lemmaID = collusage.lemmaID_u
ORDER BY lemma.lemmaID;
Also you can use aliases for table in you query like i do in first query I wrote here. It will make your life easier because you don't need to type whole name of table over and over...
GL!
P.S. also it's good to post your desired result in you question and provide SQL Fiddle with some data for our better understanding of your queston...
EDIT
After we consulted in the comments we come to this solution:
SELECT *
FROM lemma
INNER JOIN collocates
ON lemma.lemmaID = collocates.lemmaID
INNER JOIN collusage
ON collusage.collocateID_u = collocates.collocateID
AND lemma.lemmaID = collusage.lemmaID_u
INNER JOIN (SELECT post.lemmaID_p AS lemmaID, group_concat(part.partofspeech SEPARATOR ', ') AS partofspeach
FROM partofspeech part
INNER JOIN postolemma post
ON part.posID = post.posID_p
INNER JOIN lemma l
ON post.lemmaID_p = l.lemmaID
GROUP BY post.lemmaID_p) tmp
ON lemma.lemmaID = tmp.lemmaID
ORDER BY lemma.lemmaID;
Here is SQL Fiddle for that...

php foreach in foreach in foreach

This is a hypothetical question. If I have 3 arrays from 3 separate sql db queries that all relate to another. For example...
//db
schools
id | school_name
classes
id | class_name | school_id
students
id | student_name | class_id
And I want to display everything in a huge list like this...
//php
foreach(schools as school){
echo '<h1>' . $school->school_name . '<h1>';
foreach(classes as class){
if($class->school_id == $school->id){
echo '<h2>' . $class->class_name . '<h2>';
foreach(students as student){
if($student->class_id == $class->id){
echo '<h3>' . $student->student_name . '<h3>';
}
}
}
}
}
I have to make 3 database calls. Is there a way to grab all this information in a single db query? Like maybe an array in an array in an array and then somehow loop through? Or is this the best way to do this?
You can do a join which will allow you to have 1 for each. Are you wanting everything or any sort of filter ?
You can join those table, to get one big array with flattened data. When looping through this data, you can check if the id of the previous record still matches the id of the current record. If not, you can output a new header. It is important, though, that the resultset is properly sorted for this.
SELECT
s.id AS school_id,
s.school_name,
c.id AS class_id,
c.class_name,
st.id AS student_id,
st.student_name
FROM
schools s
INNER JOIN classes c ON c.school_id = s.id
INNER JOIN students st ON st.class_id = c.id
ORDER BY
s.id,
c.id,
st.id
If you have it all in a flattened structure, you can even make it into a nested array structure again something like this:
foreach ($resultset as $row)
{
$schools[$row->school_id]->school_name =
$row->school_name;
$schools[$row->school_id]->classes[$row->class_id]->class_name =
$row->class_name;
$schools[$row->school_id]->classes[$row->class_id]->students[$row->student_id]->student_name =
$row->student_name;
}
var_dump($schools);
After that, you can still use the nested for loops to process the array, but it will be in a more efficient way, since the data is already sorted out: classes are already added to the school they belong to, and student are already added to the right class.
<?php
try {
$pdo = new PDO("mysql:host=127.0.0.1;dbname=school", "username");
} catch (PDOException $e) {
echo "PDO Connection failed: " . $e->getMessage();
exit(1);
}
$sql = <<<SQL
SELECT schools.school_name, classes.class_name, students.student_name
FROM
schools INNER JOIN classes ON (schools.id = classes.school_id)
INNER JOIN students ON (classes.id = students.class_id)
ORDER BY 1, 2;
SQL;
$result = $pdo->query($sql);
if ($result == false) {
die("query failed?!");
}
$school = "";
$class = "";
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
if ($school != $row['school_name']) {
$school = $row['school_name'];
echo "\nSchool: $school\n\n";
}
if ($class != $row['class_name']) {
$class = $row['class_name'];
echo " Class: $class\n\n";
echo " Student list:\n";
}
echo " {$row['student_name']}\n";
}
$res = mysql_query('SELECT school_name, class_name, student_name, sc.id AS scid, c.id AS cid, st.id AS stid FROM schools sc LEFT JOIN classes c ON (sc.id = c.school_id) LEFT JOIN students st ON (c.id = st.class_id) ');
$arr = array();
while ($v = mysql_fetch_assoc($res)) {
$arr[$v['school_name']][$v['class_name']][$v['stid']] = $v['student_name'];
}
print_r($arr);
You could do it all in one SQL query that might look something like:
SELECT schools.schoolname, classes.class_name, students.student_name
FROM
schools INNER JOIN classes ON (schools.id = classes.school_id)
INNER JOIN students ON (classes.id = students.class_id)
ORDER BY 1, 2;
Then you could walk the result set in one loop, but you'd probably want to add some logic to only display the school name and class name once for each time it changes.

How to show all matched keyword

Im new in PHP and I have create a table (bookstore) really look like this
no_id | author | id_book | id_topic | quote | comments | no_page
id_book and id_topic have another table eg
table for book
:
id_book | book_name
table for topic
:
id_topic | topic_name
I made this sql statement for show the output in my system,but my problem is the system show only one output when submit a keyword. even though there are few similar word in the database.
"SELECT a.*, b.book_name
FROM bookstore AS a
LEFT JOIN book AS b ON a.id_book=b.id_book
WHERE quote LIKE '%".
can anyone help me how to show all match quote? i am so confuse *_*
Edit:
This is my php code.
$colname_Recordset1 = "-1";
if (isset($_GET['quote'])) {
$colname_Recordset1 = $_GET['quote'];
}
mysql_select_db($database_config, $config);
$query_Recordset1 = "SELECT a.*, b.book_name FROM bookstore a
LEFT OUTER JOIN book b ON a.id_book = b.id_book
WHERE a.quote LIKE '%'". $colname_Recordset1."%%'";
$Recordset1 = mysql_query($query_Recordset1, $config)
or die(mysql_error());
$row_Recordset1 = mysql_fetch_assoc($Recordset1);
$totalRows_Recordset1 = mysql_num_rows($Recordset1);
I think, if I understand correctly, that your query should be more like:
SELECT a.*, b.book_name
FROM bookstore a
LEFT OUTER JOIN book b ON a.id_book = b.id_book
WHERE a.quote LIKE '%'
If you are still getting a single result (where you know there is more than one result), you need to post the PHP code you are using to extract records from the DB.
You should fetch the result like this, reference http://www.php.net/manual/en/function.mysql-fetch-assoc.php
while ($row = mysql_fetch_assoc($Recordset1)) {
print_r($row);
}
and you should escape the user input with mysql_escape_string, the full php code
mysql_select_db($database_config, $config);
$filter = '';
if (isset($_GET['quote'])) {
$filter = " WHERE a.quote LIKE '%" . mysql_escape_string($_GET['quote']) . "%'";
}
$result = mysql_query(
"SELECT a.*, b.book_name FROM bookstore a
LEFT OUTER JOIN book b ON a.id_book = b.id_book" . $filter,
$config
) or die(mysql_error());
while ($row = mysql_fetch_assoc($result)) {
// If you need to output table, put the code here
print_r($row);
}

MySQL use inner join in PHP

I have 2 tables, the unique id's in each table are the same in both tables.
How do I go about joining the data from both tables together in php?
When I normally pull data I do it like this:
$get_board_array = mysql_query("SELECT * FROM posts WHERE user_id_to = '$id' ");
while($posts = mysql_fetch_array($get_board_array))
{
$post_id = $get_post['post_id'];
$html_output .= "<p>".$post_id."</p>";
}
As for pulling the data from separate tables and not getting it all mixed up, I was thinking of doing something like this:
$get_arrayA = mysql_query("SELECT * FROM tableA WHERE age = '36' ");
while($dataA = mysql_fetch_array($get_arrayA))
{
$dataA_id = $dataA['id'];
$dataA_firstName = $dataA['FirstName'];
foreach($dataA_id)
{
$get_arrayB = mysql_query("SELECT * FROM tableB where id='".$dataA_id."'");
while($dataB = mysql_fetch_array($get_arrayB))
{
$dataB_lastName = $dataB['LastName'];
$html_output .= "<p>".$dataA_firstName.$dataB_lastName"</p>";
echo $html_output;
}
}
}
Or would this be just too weird of a thing?
I know how to do it within SQL using inner join but how do I do something like that in PHP and output html?
It is because of you misguide use of wildcard (*) characters. STOP THAT !! This is what happens when arrogant php developers imagine that they do not need to learn SQL. If you need something , then select it.
SELECT
foo.foo_id,
foo.data as paramX ,
bar.type,
bar.something_else
FROM foo
INNER JOIN bar USING (foo_id)
WHERE
foo.state = 'open'
AND bar.type = 3
This (I'm just guessing the schema and your needs) could be a better query for your situation:
SELECT a.id,a.FirstName,b.LastName
FROM tableA a
JOIN tableB b ON b.id = a.id
WHERE a.age = '36'

Categories