PHP: Left Join 2 table and print all records - php

I have two table records in my database which look like this:
Table 1 with the column 1:
topic_id name
21 my computer
table 2 with columns as follows:
reply_id topic_id message
1 21 blabla
2 21 blue
In which the topic_id column in the table 2 is the foreign key of the table 1
I wanted to echo all replies in the table 2 along with the topic name (#21) in the table 1. So, I made the query like this
$q="SELECT name, message
FROM table1
LEFT JOIN table2
ON table1.topic_id = table2.topic_id
";
However, the result/ output returns the topic's name and ONLY ONE reply, but not 2 (or all) as expected. Did I miss something?
I used LEFT JOIN because some topics are still waiting for replies. In case that there is not any reply, the topic's name is still printed in browsers.
I also tried adding
GROUP BY table1.topic_id
but still NO LUCK!
Can you help? Thanks
EDIT: To clarify the question I add the php code to fetch records as follows:
As you know, The name needs to be printed only once. So, I code like this:
$tid = FALSE;
if(isset($_GET['qid']) && filter_var($_GET['qid'], FILTER_VALIDATE_INT, array('min_range'=>1) ) ){
// create the shorthand of the question ID:
$tid = $_GET['tid'];
// run query ($q) as shown above
$r = mysqli_query($dbc, $q) or die("MySQL error: " . mysqli_error($dbc) . "<hr>\nQuery: $q");
if (!(mysqli_num_rows($r) > 0) ){
$tid = FALSE; // valid topic id
}
}//isset($_GET['qid']
if ($tid) { //OK
$printtopic = FALSE; // flag variable to print topic once
while($content = mysqli_fetch_array($r, MYSQLI_ASSOC)){
if (!$printtopic) {
echo $content['name'];
$printtopic= TRUE;
}
}
} // end of $tid
// Print the messages if any:
echo $content['message'];

Try this with inner join
$q="SELECT name, message
FROM table1
INNER JOIN table2
ON table1.topic_id = table2.topic_id";

Try:
$q="SELECT table2.reply_id, table1.name, table2.message
FROM table2
LEFT JOIN table1
ON table1.topic_id = table2.topic_id
";

After struggling with this issue, I can find out that the problem is that I had to change the query to INNER JOIN and add the WHERE clause like this:
WHERE table2.reply_id = {the given topic_id}
Then it works well!
Sorry to disturb you all!

Related

Working with 2 tables PHP & MySQL

I am working on a webpage that displays list of shops. I have 2 tables, shops and shops_sched.
+-shops-+
| id | title |
+-------------shops_sched-------------+
| id | shops_id | start_date | end_date |
Basically, the program displays the list of shops from the shops table, but if a value from shops.id is found # shops_sched.shops_id the page must output shops.title + 'coming soon'.
I understand this will be easy if I just place the date fields inside the table shops but due to programming restrictions I can't. I'm working on an existing project and I'm trying to minimize changes to existing functions. I can create new PHP functions if necessary though.
In addition, I need to get all the entries from the shops table. The Program needs to return all shops.title but for those shops whose id is found # shops_sched.shops_id, the program will have to return shops.title + "Coming Soon".
must output shops.title + 'coming soon'.
So do it like this:
$shops.title = "Donut-John";
echo $shops.title." coming soon";
To join the shops and shops_sched table
$query = SELECT `title` FROM `shops` JOIN `shops_sched` ON `shops`.`id` = `shops_sched`.`shops_id` WHERE `shops_sched`.`shop_id` = 5;
$result = mysql_query($query);
while($row = mysql_fetch_array($result) {
echo $row['title'] . 'coming soon';
}
For more about join you also can refer the following link
https://dev.mysql.com/doc/refman/5.0/en/join.html
http://www.tutorialspoint.com/mysql/mysql-using-joins.htm
Join the two tables :
SELECT shops.title
FROM shops INNER JOIN shops_sched ON shops.id = shops_sched.shops_id
The query should return only the the shops inside shops_sched
EDIT :
If I understood your question, try this :
SELECT shops.title, shops_sched.id
FROM shops LEFT JOIN shops_sched ON shops.id = shops_sched.shops_id
This will return all the titles, and the shops_sched.shops_id if shops.id = shops_sched.shops_id. In the other case, the hops_sched.shops_id will be null
Then you fetch the rows and if the second row is not null, print title + coming soon
Sample code : (Something like this)
$query = "SELECT `title`, 'shops_id' FROM `shops` LEFT JOIN `shops_sched` ON `shops`.`id` = `shops_sched`.`shops_id` WHERE `shops_sched`.`shop_id`";
$result = mysql_query($query);
while($row = mysql_fetch_array($result) {
if($row['shops_id'] != "")
{
echo $row['title'] . ' coming soon';
}
else
{
echo $row['title'];
}
}

Cross selection of two columns in a mysql table

I have a mysql table consisting of users following other users. I can query what other users a specific user (me) is following, and I can also query who are following a specific user (me). These are two lists. What I cannot query is when I have a list of people following me I need to know which one of them I am following back.
It's like Tim, Peter and Suzy are following me and I follow Tim and Suzy from the 3 of them.
This is my table: the people in the USER_ID column are following the people in the FOLLOW_ID column.
Query the list of people following me: (I am the ID ending in 26):
$userid = '000000000026';
$i = 0;
try {
$stmt = $conn->prepare("SELECT USER_ID FROM FOLLOW WHERE FOLLOW_ID=?");
$stmt -> execute(array($userid));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$row2[$i] = $row['USER_ID'];
$i++;
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
$response["success"] = 0;
}
for ($c=0; $c<$i; $c++) {
echo 'USER_ID FOLLOWING ME: ' . $row2[$c] . '<br>';
}
The result:
USER_ID FOLLOWING ME: 000000000030
USER_ID FOLLOWING ME: 000000000033
USER_ID FOLLOWING ME: 000000000028
So these three people are following me as you can see from the table as well.
Now I want to know which one of these three do I follow. I don't know if getting a list of the people I am following and then matching the two lists are efficient. Based on this list I follow 4 people. I see that two of them are following me (IDs ending in 28 and 33) and I want to have this information as a result.
Desired result:
USER_ID FOLLOWING ME: 000000000030, NoFollow
USER_ID FOLLOWING ME: 000000000033, Follow
USER_ID FOLLOWING ME: 000000000028, Follow
I have only mediocre knowledge of sql so please ignore advanced techniques or provide an explanation please. Thank you.
Try this way:
select distinct t1.user_id, t1.follow_id,
IF (t2.user_id IS NULL, 'NoFollow', 'Follow') AS Following
from test t1 left join
test t2 on ( t2.follow_id = t1.user_id
and t1.follow_id = t2.user_id)
where t1.user_id = 26
See it here on fiddle: http://sqlfiddle.com/#!2/f108c/31
select f1.follow_id , f2.user_id as followed_back
from follows f1 left join
follows f2 on (f2.follow_id = f1.user_id and f1.follow_id = f2.user_id)
where f1.user_id = 1
This query returns null if the user isn't following back or it's id if the user is following back
demo here
UPDATE:
new demo here. pretty much the same. if you follow back the user you get your id back. If not you get a null
select f1.user_id , f2.user_id as followed_back
from follows f1 left join
follows f2 on (f2.follow_id = f1.user_id and f1.follow_id = f2.user_id)
where f1.follow_id = 1

SQL Query Grabbing data from two tables

My code right now is this
$extract = mysqli_query($dbc, "SELECT * FROM items");
$numrows = mysqli_num_rows($extract);
while($row = mysqli_fetch_assoc($extract)) {
$id = $row['i_id'];
$iname = $row['i_name'];
echo "<tr><td><a href='capture.php?item_id=$id'>$iname</a></td><td>Incomplete</td></tr>";
}
What i want to do is run a check to see if the item has already been completed.
I have a separate table that contains the information, for instance say that Item 1 has been completed then I would like to be able to change my echo to something like:
echo "<tr><td>$iname</td><td>Complete!</td></tr>";
How would I accomplish this? Would I need to use some form of a join statement?
I want to be able to display all the items in the table but not duplicate them i initially thought that an if statement on the echo to see if item complete then do this else do that
Here are the two tables
Items item_collection
------ ---------------
i_id i_id
i_name complete
caption
image
c_id
g_id
You can use join condition like this (assuming complete is a varchar field)
SELECT a.i_id, a.i_name,
CASE WHEN i_status = '1' THEN 'Complete!' ELSE 'Incomplete' END AS complete_status
FROM items a
LEFT OUTER JOIN item_collection b ON a.i_id = b.i_id
select
case
when ic.complete = 1 then 'Complete'
else 'Incomplete'
end as item_status
from items i
left join item_collection ic on i.i_id = ic.i_id
where i.i_name = 'your_item_name'
Assuming that ic.complete = 1 when item is complete.
Something along the lines of SELECT * FROM table1 WHERE table1.id not in (SELECT Id FROM table2)

Join of 3 Tables - How to walk through results?

I have this sql statement joining 3 tables:
SELECT * FROM `int_news`
LEFT JOIN tl_member ON int_news.member_id = tl_member.id
LEFT JOIN tl_news ON int_news.news_id = tl_news.id
The 3 Tables are like this:
Table 1 (int_news)
ID, member_id, news_id
Table 2 (tl_member)
id, firstname, lastname
Table 3 (tl_news)
id, headline
So far so good, but it seems i have a big blackhole in my head making me unable to solve how to output the result like this
For each "headline" i want ALL lastnames e.g.
headline 1 Jonny
Walker
Jim
headline 2 Knopf
Jon
Doe
It sounds your looking something like a pivot so if you group your query by headline, it will display each lastname as a column.
I found this good tutorial on pivots for mysql that might help you http://www.artfulsoftware.com/infotree/queries.php#78
headline 1 Jonny Walker Jim
headline 2 Knopf Jon Doe
Here is a loop that would do that *Forgive my php it's been a while.
$curHeadline = "";
while ( $db_field = mysql_fetch_assoc($result) ) {
if($curHeadline != $db_field['headline'])
{
$curHeadline = $db_field['headline'];
print $curHeadline . $db_field['ID']
}
print $db_field['lastName'] . "<BR>";
}
Try this for mysql :
SELECT tlnews.headline, GROUP_CONCAT(tl_member.last_name)
FROM `int_news` LEFT JOIN tl_member ON int_news.member_id = tl_member.id
LEFT JOIN tl_news ON int_news.news_id = tl_news.id
GROUP BY 1;
Expected Output:
headline1 Johnny,Walker,Jim
headline2 Knopf,Jon,Doe
...
Would something like this vaguely reflect your situation?
<?php
$sql = "
SELECT
`int_news`.`ID` AS `int_news_ID`,
`int_news`.`member_id`,
`int_news`.`news_id`,
`t1_member`.`id` AS `t1_member_id`,
`t1_member`.`firstname`,
`t1_member`.`lastname`, /* desired */
`t1_news`.`id` AS `t1_news_id`,
`t1_news`.`headline` /* desired */
FROM
`int_news`
LEFT JOIN `tl_member` ON `int_news`.`member_id` = `tl_member`.`id`
LEFT JOIN `tl_news` ON `int_news`.`news_id` = `tl_news`.`id`
";
$res = mysql_query($query);
$arrHeadings = array();
while($row = mysql_fetch_assoc($res)) {
// We want to output the results in groups of headings
$arrHeadings[$row['heading']][] = $row;
}
// Don't forget to cleanse for html output (unlike below)
// Loop through the headers
foreach($arrHeadings as $heading=>$arrRow) {
echo '<dl>';
echo '<dt>'.$heading.'</dt>';
echo '<dd>';
// Loop through rows with the same header
foreach($arrRow as $index=>$dbRow) {
echo $dbRow['lastname'].'<br />';
}
echo '</dd>';
echo '</dl>';
}
?>

mysql return the total of rows for each user_id

$sql = "SELECT * FROM books LEFT JOIN users
ON books.readby=users.user_id WHERE users.email IS NOT NULL";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
{
echo $row['readby']. " - read 10 books";
} //while ends
this is the code I have so far. I am trying to retrieve the number of books read by each user
and echo the results. echo the user_id and number of books he/she read
books table is like this : id - name - pages - readby
the row readby contains the user id.any ideas/suggestions? I was thinking about using count() but Im not sure how to go about doing that.
A subquery can return the count of books read per user. That is left-joined back against the main table to retrieve the other columns about each user.
Edit The GROUP BY had been omitted...
SELECT
users.*,
usersread.numread
FROM
users
/* join all user details against count of books read */
LEFT JOIN (
/* Retrieve user_id (via readby) and count from the books table */
SELECT
readby,
COUNT(*) AS numread
FROM books
GROUP BY readby
) usersread ON users.user_id = usersread.readby
In your PHP then, you can retrieve $row['numread'] after fetching the result.
// Assuming you already executed the query above and checked errors...
while($row = mysql_fetch_array($result))
{
// don't know the contents of your users table, but assuming there's a
// users.name column I used 'name' here...
echo "{$row['name']} read {$row['numread']} books.";
}
You can use count() this way:
<?php
$count = mysql_fetch_array(mysql_query("SELECT COUNT(`user_id`) FROM books LEFT JOIN users ON books.readby=users.user_id WHERE users.email IS NOT NULL GROUP BY `user_id`"));
$count = $count[0];
?>
Hope this helps! :)

Categories