Generate html table based on 2x mysql db queries - php

I'm trying to show stuff queried from two tables, but on one html table. Data is shown for the last 30 days, based on which, an html table is being generated.
Currently I'm stuck using two queries and generating two html tables:
$query1 = mysqli_query( $con, "SELECT date, stuff* " );
while( $record = mysqli_fetch_array( $query1 ) ){
echo '<html table generated based on query>';
}
$query2 = mysqli_query( $con, "SELECT date, other stuff*" );
while( $record = mysqli_fetch_array( $query2 ) ){
echo '<another html table generated based on query2>';
}
Is there a possibility to show both queries on one html table instead?
Note that it gets tricky since we have dates on one table which are not necessarily found in the second table or vice-versa.
Thanks for the support guys. So far I'm stuck at this:
SELECT * FROM user_visit_logs
LEFT JOIN surfer_stats ON user_visit_logs.date = surfer_stats.date
UNION
SELECT * FROM user_visit_logs
RIGHT JOIN surfer_stats ON user_visit_logs.date = surfer_stats.date
The query completes, but the 2nd table fields are all null:
Furthermore, it breaks when I add additional clause like:
WHERE user_id = '{$_SESSION['user_id']}' ORDER BY date DESC LIMIT 30

I think you are after FULL OUTER JOIN concept:
The FULL OUTER JOIN keyword returns all rows from the left table (table1) and from the right table (table2)
In which you may use common dates as a shared row.
So the query will get to simple one:
$query = "
SELECT table1.date, stuff
FROM table1
LEFT OUTER JOIN table2 ON table1.date = table2.date
UNION
SELECT table2.date, other_stuff
FROM table1
RIGHT OUTER JOIN table2
ON table1.date = table2.date
";
$result = mysqli_query( $con, $query );
while( $record = mysqli_fetch_array( $result ) ){
echo '<html table generated based on query>';
}
Example
This is an schematic diagram of FULL OUTER JOIN concept:

After running into quite a few bumps with this one, I finally managed to merge 2 columns from each table and also to use where and sort clauses on them with the following query:
( SELECT user_visit_logs.user_id,user_visit_logs.date,unique_hits,non_unique_hits,earned,sites_surfed,earnings FROM user_visit_logs
LEFT OUTER JOIN surfer_stats ON user_visit_logs.user_id = surfer_stats.user_id AND user_visit_logs.date = surfer_stats.date where user_visit_logs.user_id = 23 ORDER BY date DESC LIMIT 30 )
UNION
( SELECT surfer_stats.user_id,surfer_stats.date,unique_hits,non_unique_hits,earned,sites_surfed,earnings FROM user_visit_logs
RIGHT OUTER JOIN surfer_stats ON user_visit_logs.user_id = surfer_stats.user_id AND user_visit_logs.date = surfer_stats.date where user_visit_logs.user_id = 23 LIMIT 30 )
Simplified, "user_visit_logs" and "surfer_stats" were the 2 tables needed to be joined.

Absolutely. Just pop them both into a variable:
$data = '';
$query = mysqli_query($con,"SELECT date, stuff* ");
while($record = mysqli_fetch_array($query)) {
$data.= '<tr><td>--Your Row Data Here--</td></tr>';
}
$query2 = mysqli_query($con,"SELECT date, other stuff*");
while($record = mysqli_fetch_array($query2)) {
$data .= '<tr><td>--Your Row Data Here--</td></tr>';
}
echo "<table>$data</table>";
Instead of using echo in your loop, you're just storing the results in $data. Then, you're echoing it out after all data has been added to it.
As for your second point, it's not a big deal if fields don't exist. If they're null, you'll just have a column that doesn't have data in it.
Here's an example with fake column names:
$data = '';
$query = mysqli_query($con,"SELECT date, stuff* ");
while($record = mysqli_fetch_array($query)) {
$data.= "<tr><td>{$record[id]}</td><td>{$record[first_name]}</td><td>{$record[last_name]}</td></tr>";
}
$query2 = mysqli_query($con,"SELECT date, other stuff*");
while($record = mysqli_fetch_array($query2)) {
$data .= "<tr><td>{$record[id]}</td><td>{$record[first_name]}</td><td>{$record[last_name]}</td></tr>";
}
echo "<table><tr><th>ID</th><th>First Name</th><th>Last Name</th></tr>$data</table>";
I have a feeling I may have misunderstood the need. If so, I apologize. If you can elaborate just a bit more I can change my answer :)

Related

SELECT a value multiple time in SQL

I have a code in PHP where I want to display multiple times values, and so, even if these values are the same between them. My code is simple :
$sql = "SELECT photo from table WHERE username IN ('1','2','2') ORDER BY id DESC ";
$res = array();
$result = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($result)){
array_push($res, $row['photo']);
}
echo json_encode($res);
But this code only display (in json) an array of two values (because the values of photo of the username 2 are the same).
What I want to achieve is to make an array with the exact same number of values of the number of username I defined WHERE username IN ('1','2','2') (so here, 3 values).
I hope you understood me, thanks for helping me !
I think what you're after is to list even the duplicates in the end result. As your SQL will only retrieve the unique items, the idea would be to include the username in the SQL result set. Then use the original list of user names ($userNames) and add in the photo for each of them.
I've used mysqli_fetch_all() to simplify the process of fetching all of the data, then used array_column() to make the username the key for the photos.
$userNames = array(1,2,2);
$sql = "SELECT username, photo
from table
WHERE username IN ('".implode("','", $userNames)."')
ORDER BY id DESC ";
$res = array();
$result = mysqli_query($con,$sql);
$photos = mysqli_fetch_all($result, MYSQLI_ASSOC);
$photos = array_column($photos, "photo", "username");
foreach ( $userNames as $user ) {
if ( isset($photos[$user])) {
$res[] = $photos[$user];
}
else {
$res[] = '';
}
}
echo json_encode($res);
You would use left join:
select t.photo
from (select '1' as username union all select '2' union all select '3'
) u left join
table t
on t.username = u.username
order by t.id desc;
Note this will return rows, even when the user name does not exist. If you want to filter those rows, remove the left so you are doing an inner join.

PHP Query MySQL Tables from IDs from other tables

I have a database with several tables. I'm able to query IDs from a single table. What I'd like to do is Use those IDs to query another tables IDs, then use these new IDs to query fields from the final table. Here is what I am currently doing:
Here is how I acquire the first set of IDs:
$returnedPost = mysqli_query($con, "SELECT Region_ID FROM Region WHERE RegionName='" . $queryVar . "'");
function resultToArray($result) {
$rows = array();
while ($row = $result->fetch_assoc()) {
$rows[] = $row;
}
return $rows;
}
$rows = resultToArray($returnedPost);
//$rows[x]['Region_ID'];//returns Region_ID 1...n
I'd like to use the IDs in $rows to be able to query a new set of IDs from other tables as follows:
$newTbl = mysqli_query($con, "SELECT Location_ID FROM Location WHERE Region_ID=" . $rows[$x]['Region_ID']);
$rows2 = resultToArray($newTbl);
$finalTbl = mysqli_query($con, "SELECT Field1, Field2 FROM Posts WHERE Location_ID=" . $rows2[$x]['Location_ID']);
Can someone please tell me how I can accomplish this? Thanks.
you can use INNER JOIN in one query to get at this data, maybe something like this
SELECT P.Field1,P.Field2
FROM Region R
INNER JOIN Location L ON R.Region_ID = L.Region_ID
INNER JOIN Posts P ON L.Location_ID = P.Location_ID
WHERE R.RegionName = Your_Region_QueryVar

Counting the number of times each variable appears in table

Basically, I am seeking to know if there is a better way to accomplish this specific task.
Basically, what happens is I query the db for a list of "project needs" -- These are each uniquer and only appear once.
Then, I search another table to find out how many members have the required "skills - which are directly correlated to the project needs".
I accomplished exactly what I was trying to do by running a second query and then inserting them into an array like this:
function countEachSkill(){
$return = array();
$query = "SELECT DISTINCT SKILL_ID, SKILL_NAME FROM PROJECT_NEEDS";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_num_rows($result);
while($row = mysql_fetch_assoc($result)){
$query = "SELECT COUNT(*) as COUNT FROM MEMBER_SKILLS WHERE SKILL_ID = '".$row['NEED_ID']."'";
$cResult = mysql_query($query);
$cRow = mysql_fetch_assoc($cResult);
$return[$row['SKILL_ID']]['Count'] = $cRow['COUNT'];
$return[$row['SKILL_ID']]['Name'] = $row['SKILL_NAME'];
}
arsort($return);
return $return;
}
But I feel like there has to be a better way (perhaps using some kind of join?) that would return this in a result set to avoid using the array.
Thanks in advance.
PS. I know mysql_ is depreciated. It is not my choice on which to use.
SELECT P.SKILL_ID, P.SKILL_NAME, COUNT(M.SKILL_ID) as COUNT FROM PROJECT_NEEDS P INNER JOIN MEMBER_SKILLS M
ON P.SKILL_ID=M.SKILL_ID
GROUP BY P.SKILL_ID, P.SKILL_NAME
I've adjusted Nriddens answer to accomodate for the select distinct, Im under the belief that his adjustment would be ok given SKILL_ID is a primary key
function countEachSkill(){
$return = array();
$query = "
SELECT
COUNT(*) AS COUNT,
PROJECT_NEEDS.SKILL_NAME,
PROJECT_NEEDS.SKILL_ID
FROM
(SELECT DISTINCT
SKILL_ID, SKILL_NAME
FROM
PROJECT_NEEDS) AS PROJECT_NEEDS
INNER JOIN
MEMBER_SKILLS
ON
MEMBER_SKILLS.SKILL_ID = PROJECT_NEEDS.SKILL_ID
GROUP BY PROJECT_NEEDS.SKILL_ID";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_num_rows($result);
while($row = mysql_fetch_assoc($result)){
$return[$row['SKILL_ID']]['Count'] = $row['COUNT'];
$return[$row['SKILL_ID']]['Name'] = $row['SKILL_NAME'];
}
arsort($return);
return $return;
I am subquerying on the select distinct because I dont believe you have a dedicated skills table with an auto inc primary key, if that was there I wouldn't be using a subquery.
Can you test this query
select project_needs.*,count(members_skills.*) as count from project_needs
inner join members_skills
on members_skills.skill_id=project_needs.skill_id Group by project_needs.skill_name, project_needs.skill_id

How to optimize nested query with PHP and MySqli?

I have this code, that fetches data from two tables in MySQLi.
It first has to get the title, description, status and project_id from table 1, and then get the name from table 2 using the id from table 1.
Is there a better/faster way to do this? I have about 600 rows in the tables, and it takes about 5 sec to run this query. I will also add that this example is a bit simplified, so please don't comment on the db-structure.
<?php
$results = $connect()->db_connection->query(
'SELECT title, description, status, project_id
FROM table
WHERE created_by ='.$user_id
);
if ($results) {
while ($result = $results->fetch_object()) {
$res = $connect()->db_connection->query(
"SELECT name FROM projects WHERE id = ".$result->project_id
);
if ($res) {
while ($r = $res->fetch_object()) {
echo $r->name;
}
}
echo $result->title;
echo $result->status;
}
}
?>
Use Query:
SELECT title,description,status,project_id
FROM table tb
inner join projects pr on pr.id = tb.project_id
WHERE created_by = $user_id
Try to use JOIN in your query.
You can find examples and description of this command here: http://www.w3schools.com/sql/sql_join.asp
Check out also this infographics:
http://www.codeproject.com/KB/database/Visual_SQL_Joins/Visual_SQL_JOINS_orig.jpg
You can use JOIN on project_id:
$results = $connect()->db_connection->query('SELECT t.title title,t.description,t.status status,t.project_id, p.name name FROM `table` t JOIN projects p ON p.id= t.project_id WHERE t.created_by ='.$user_id);
if($results){
while($result = $results->fetch_object()){
echo $result->name;
echo $result->title;
echo $result->status;
}
}
tables have aliases here - t for table and p for projects.
Also to make it faster, add index to project_id in table table, if you haven't done it yet:
$connect()->db_connection->query('ALTER TABLE `table` ADD INDEX `product_id`');

add value to result from mysql query that will be JSON encoded in PHP?

I would like to add a value to each row that I get from my query depending on if a row exist in another table. Is there a smart way to achieve this?
This is the code I have:
$sth = mysql_query("SELECT tbl_subApp2Tag.*, tbl_tag.* FROM tbl_subApp2Tag LEFT JOIN tbl_tag ON tbl_subApp2Tag.tag_id = tbl_tag.id WHERE tbl_subApp2Tag.subApp_id = '".$sub."' ORDER BY tbl_tag.name ASC");
if(!$sth) echo "Error in query: ".mysql_error();
while($r = mysql_fetch_assoc($sth)) {
$query = "SELECT * FROM tbl_userDevice2Tag WHERE tag_id='".$r['id']."' AND userDevice_id='".$user."'";
$result = mysql_query($query) or die(mysql_error());
if (mysql_num_rows($result)) {
$r['relation'] = true;
$rows[] = $r; //Add 'relation' => true to this row
} else {
$r['relation'] = false;
$rows[] = $r; //Add 'relation' => false to this row
}
}
print json_encode($rows);
Where the //Add ... is, is where I would like to insert the extra value. Any suggestions of how I can do this?
I'm still a beginner in PHP so if there are anything else that I have missed please tell me.
EDIT: Second query was from the wrong table. This is the correct one.
Edited Edited below query to reflect new information because I don't like leaving things half-done.
$sth = mysql_query("
SELECT
tbl_subApp2Tag.*,
tbl_tag.*,
ISNULL(tbl_userDevice2Tag.userDevice_id) AS relation
FROM tbl_subApp2Tag
LEFT JOIN tbl_tag
ON tbl_tag.id = tbl_subApp2Tag.tag_id
LEFT JOIN tbl_userDevice2Tag
ON tbl_userDevice2Tag.tag_id = tbl_tag.id
AND tbl_userDevice2Tag.userDevice_id = '".$user."'
WHERE tbl_subApp2Tag.subApp_id = '".$sub."'
ORDER BY tbl_tag.name ASC
");
Though the above feels like the LEFT JOIN on tbl_tag is the wrong way around, but it's hard to tell as you are vague on your eventual aim. For example, if I was to assume the following
Tags will always exist
subApp2Tag will always exist
You want to know if a record in tbl_userDevice2Tag matches the above
Then I would do the following instead. The INNER JOIN means that it won't worry about records in tbl_tag that are not on the requested subApp_id which in turn will limit the other joins.
$sth = mysql_query("
SELECT
tbl_subApp2Tag.*,
tbl_tag.*,
ISNULL(tbl_userDevice2Tag.userDevice_id) AS relation
FROM tbl_tag
INNER JOIN tbl_subApp2Tag
ON tbl_subApp2Tag.tag_id = tbl_tag.id
AND tbl_subApp2Tag.subApp_id = '".$sub."'
LEFT JOIN tbl_userDevice2Tag
ON tbl_userDevice2Tag.tag_id = tbl_tag.id
AND tbl_userDevice2Tag.userDevice_id = '".$user."'
ORDER BY tbl_tag.name ASC
");
you have to do all the job in a single query.
Why can't you just $r['append'] = "value"; before adding $r to the array?

Categories