mysqli union arrange results per talbe - php

I'm using a mysqli union to search the database like so:
$search = security($_POST['search']);
$search_val = "%{$search}%";
$search_disp = '';
if($searchQ = $db->prepare(
"(SELECT name AS `name1` FROM `table1` WHERE name LIKE ? LIMIT 8)
UNION
(SELECT heading AS `name2` FROM `table2` WHERE heading LIKE ? LIMIT 8)
")){
if($searchQ->bind_param("ss",$search_val,$search_val)){
if($searchQ->execute()){
$searchQ->store_result();
if($searchQ->num_rows){
$searchQ->bind_result($search_result);
while($searchQ->fetch()){
$search_disp.='
<div>'.$search_result.'</div>
';
}
}
}
else{echo '$db->error' exit();}
}
else{echo '$db->error' exit();}
}
else{echo '$db->error' exit();}
echo $search_disp; exit();
What I dont know how to achieve is display a different result depending on the table it came from since I'm fetching both results as the same varialbe ($search_result), for example:
if(result from table one){
$search_disp.='
<div class="talbe1">'.$search_result.'</div>
';
}
else if(result from table two){
$search_disp.='
<div class="talbe2">'.$search_result.'</div>
';
}
Can someone please help me with that?

You can add additional row tbl to result set and then use it:
(SELECT 'table1' as tbl, name FROM `table1` WHERE name LIKE ? LIMIT 8)
UNION
(SELECT 'table2' as tbl, heading AS name FROM `table2` WHERE heading LIKE ? LIMIT 8)

Related

How to select a column in a left join if there is 2 columns with the same name ? [MySql]

I have made a LEFT JOIN to get the values from 2 tables from my database.
The query is like this:
SELECT *
FROM thread
LEFT JOIN comments ON thread.id_thread = comments.id_thread
WHERE id_type = '1'
ORDER BY data DESC, hour DESC
Then I output the values this way:
<?
while($row = mysqli_fetch_array($query))
{
echo '<div class="col-md-1"></div>';
echo '<div class="col-md-11">';
echo $row['title'] ."<br><br>".$row['content']."<br><br>";
echo $row['content_com'];
echo '<div class="col-md-2 pull-right">'. "date: ".$row['data']."<br>"."author: ".''.$row['username'].''.'</div>' ."<br><br>";
echo '<form role="form" action="commit.php" method="post"><div class="col-md-offset-1 col-md-9"><input class="form-control" type="text" name="comm"><input type="hidden" name="thread_id" value="'.$row['id_thread'].'"></div></form> <br><br><hr><br>';
echo '</div>';
}
mysqli_close($connect);
?>
Then in the commit.php (form action):
<?php
session_start();
if(isset($_SESSION['id']))
{
$servername = "mysql9.000webhost.com";
$username = "a5461665_admin";
$password = "xenovia1";
$dbname = "a5461665_pap";
$connect = mysqli_connect($servername, $username, $password, $dbname);
$id = (isset($_GET['id'])) ? $_GET['id'] : $_SESSION['id'];
$ctn = $_POST["comm"];
$com = mysqli_query($connect,"INSERT INTO comments(content_com,id_thread) values ('".$ctn."', '".$_POST['thread_id']."')");
header("location:javascript://history.go(-1)");
if (!$connect) {
die("Connection failed: " . mysqli_connect_error());
}
}
else
{
header(" url=index.php");
}
?>
My problem is that the hidden input box is passing to the form action the field id_thread from the table comments but I want it to pass the field id_thread from the table threads, how do I do that ??
SELECT *, thread.id_thread as mycol
FROM
thread LEFT JOIN comments
ON thread.id_thread=comments.id_thread
WHERE thread.id_type = '1'
ORDER BY data desc, hour desc
Specify column name with the table and alias it.
So, SELECT * for all columns as before, now taking thread.id_thread and alias it to mycol. This will be now available as mycol and no more-name clashing.
you can use "alias" or the table name - then specify which column you want to use
SELECT T.*, comments.id_thread AS comment_thread_id
FROM thread T
LEFT JOIN comments
ON thread.id_thread=comments.id_thread
WHERE id_type = '1' ORDER BY data desc, hour desc
see, T is alis for table name, thread, T.* will select all cols from thread table, comments.id_thread will take just column ID from table comments named as comment_thread_id
Next to using aliases/tablename you can also use USING() instead of ON to join the tables.
SELECT T.*, comments.id_thread AS comment_thread_id
FROM thread T
LEFT JOIN comments
USING(id_thread)
WHERE id_type = '1' ORDER BY data desc, hour desc
Here is a nice explanation of the difference between both methods: https://stackoverflow.com/a/11367066/3595565

fetch multiple value from same table using id value

I want to fetch value Rows from single table.I want to fetch sub_id for specific id.
I achieved my require ment in 2 query.I want to do it in single query.I want to display result as Event,order history,Eent Ticket,calander
$sql="select * from table1 where roles like %admin% and sub_id='0'"
$sql1=mysql_query($sql);
while($fet=mysql_fetch_assoc($sql1))
{
$id=$fet['id'];
$query="select page_name from table1 where sub_id= '$id'";
.. ..
}
Use a JOIN
SELECT t1.id, t1.sub_id, t1.page_name, t2.page_name AS parent_page
FROM table1 AS t1
JOIN table1 AS t2 ON t1.sub_id = t2.id
WHERE t2.roles like '%admin%' AND t2.sub_id = '0';
DEMO
use this
$sql="select sub_id from table1 where id='".$id."' ";
After this, use results of this as below
$sql= "select * from table1 where roles like %admin% and sub_id in($ids)";
You dont need another query to get the value of page_name just use $fet['page_name']; you already get the data of page_name in your first query.
$sub_id = $fet['sub_id'];//
echo $sub_id;//
$page_name = $fet['page_name'];//You can get and use the value of page_name here
UPDATED
if you want Event,Order History,Event Ticket and Calander
then change your where to sub_id = '2' ordered by id ascending.
$sql="select * from table1 where roles like %admin% and sub_id='2' order by id asc"
$sql1=mysql_query($sql);
while($fet=mysql_fetch_assoc($sql1))
{
echo $fet['page_name'].'<br/>';//display the page_name
}
You can also use the single query for getting page_name:
SELECT page_name FROM table1
WHERE roles LIKE %admin%
AND sub_id = 2
you can get Event,Order History,Event Ticket,Calendar as:
$sql="SELECT page_name FROM table1
WHERE roles LIKE %admin%
AND sub_id = 2";
$sql1=mysql_query($sql);
$records = array();
while($fet=mysql_fetch_assoc($sql1))
{
$records[] = $fet['page_name'];
}
echo implode(",",$records); // Event,Order History,Event Ticket,Calendar
UPDATE 1:
use sub_id = 2 for getting all page_name related to Event MAnagement
Side note:
I suggest you to use mysqli_* or PDO, instead of mysql_* because mysql_* is deprecated in not available in PHP 7.
$sql="select sub_id from table1 where id='".$id."' ";
if thats what you want.

Add 2 row counts together in MySql

I am adapting something and I need to add 2 row counts together in mysql. So far I have
<?
$result = mysql_query("SELECT * FROM Table1 WHERE Field1 ='2' ");
$num_rows = mysql_num_rows($result);
$result2 = mysql_query("SELECT * FROM Table2 WHERE Field2 ='6' ");
$num_rows2 = mysql_num_rows($result2);
$num_rows3 = ($num_rows + $num_rows2)
echo "$num_rows3";
?>
I can echo either $num_rows OR $num_rows2 fine but I need to do the calculation then echo $num_rows3.
I am probably doing something stupid here but I do not know mysql at all so I am trying to learn.
Thanks for the help!
You could also have one single query for both counts:
SELECT count(t1.id), count(t2.id)
FROM (SELECT id FROM Table1 WHERE Field1 ='2') t1,
(SELECT id FROM Table2 WHERE Field2 ='6') t2
Also note that you are missing a ; when summing the counts.
This is just a suggestion even though you got your answer.
If you want to add those into ONE MYSQLI query you could use this:
SELECT sum(cnt) from
(SELECT COUNT(*) cnt FROM T1 WHERE Field1=2 union all
SELECT COUNT(*) cnt FROM T2 WHERE Field2=6) a
I just don't see the point in fetching all data in SELECT * FROM Where all you do is mysql_num_rows($result)
Hope this helps, and maybe improves your code.
Good Luck!
Here is just a demo IN SQLFiddle, so you can see this in action:
SQLFiddle Demo
I was missing the ; after the calculation!!
Using only one query and counting before add, a possible code is
<?
$query = "SELECT c1 + c2 FROM ";
$query .= "(SELECT count(Field1) c1 FROM Table1 WHERE Field1 ='2') t1,";
$query .= "(SELECT count(Field2) c2 FROM Table2 WHERE Field2 ='6') t2";
$result = mysql_query($query);
$value = mysql_num_rows($result);
echo "$value";
?>

ORDER BY COUNT with condition

I have two tables, users and clients_closed_1.
I need to order the result by the count of the rows on the table client_closed_1 where meeting=1.
I did it for time_closed field but that was easy because there was no condition.
It's a part of a search code so I'll show you all of it.
With this code I manage to order it by meeting - but users who has no rows with meeting=1 isn't pull out from the database and I need them to show even if they doesn't have meetings.
if (project_type($_GET['project']) == 1) {
$table = 'clients_closed_1';
} else {
$table = 'clients_closed_2';
}
$s_query = "SELECT *,COUNT(time_closed) as numc FROM `".$table."` FULL JOIN `users` ON users.ID=user_c WHERE 1=1";
if (isset($_POST['search'])) {
if ($_POST['tm'] == 'da') {
$dd = strtotime($_POST['y']."-".$_POST['m']."-".$_POST['d']);
$s_query = $s_query." && DATE(FROM_UNIXTIME(time_closed)) = DATE(FROM_UNIXTIME(".$dd."))";
}
elseif ($_POST['tm'] == 'mon') {
$s_query = $s_query." && YEAR(FROM_UNIXTIME(time_closed))=".$_POST['y']." && MONTH(FROM_UNIXTIME(time_closed))=".$_POST['m'];
}
if (!empty($_POST['search_name'])) {
$s_query = $s_query." && CONCAT(p_name,' ',l_name) LIKE '%".$_POST['search_name']."%'";
}
if (!empty($_POST['level'])) {
$query = "&& (level=3 && project IN (SELECT `project` FROM `project` WHERE type='2')) || level=4";
}
} else {
$s_query = $s_query." && YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW()) && MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())";
}
if (isset($_GET['order'])) {
if ($_GET['order'] == 'closing') {
$s_query = $s_query." GROUP BY users.ID ORDER BY numc DESC";
}
elseif ($_GET['order'] == 'meeting') {
$s_query = $s_query." && meeting='1' GROUP BY users.ID ORDER BY numd DESC";
}
}
$query = $db->query($s_query);
If you need any more code/doedn't understand something comment please and I'll fix it.
Thank you.
EDIT:
example of $s_query:
SELECT *,COUNT(time_closed) as numc, COUNT(meeting) as numd FROM `clients_closed_1`
FULL JOIN `users` ON users.ID=user_c WHERE 1=1 &&
YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW()) &&
MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())
GROUP BY users.ID ORDER BY numc DESC
Im not sure I understand 100% of the criteria youre looking for but here is a rough draft of the query:
SELECT c.id, c.meeting, temp1.time_closed_count, temp2.meeting_count, temp3.status_count
FROM `clients_closed_1` c
FULL JOIN `users` u
ON c.user_c=u.ID
LEFT JOIN (SELECT time_closed, count(time_closed) time_closed_count FROM clients_closed_1 GROUP BY time_closed) temp1
ON c.time_closed = temp1.time_closed
LEFT JOIN (SELECT meeting, count(meeting) meeting_count FROM clients_closed_1 GROUP BY meeting) temp2
ON c.meeting = temp2.meeting
LEFT JOIN (SELECT status, count(status) status_count FROM clients_closed_1 GROUP BY status) temp3
ON c.status = temp3.status
WHERE 1=1
AND YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW())
AND MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())
ORDER BY {$order_criteria} DESC
Whats happeneing here is, we are doing the count of all distinct meeting values in a subquery and joining it to the original query based on the value of "meeting" for each row.
This gives us the total "meetings" grouped by distinct meeting values, without cutting out rows. Such is the same for the other 2 subqueries.
This also cleans things up a bit and allows us to just insert the $order_criteria, where that could be time_closed count, meeting_count, or status_count. Just set a default (id) in case your user does not choose anything :)
Edit: Id also recommend trying to get out of the SELECT * habit. Specify the columns you need and your output will be much nicer. Its also far more efficient when you start dealing with larger tables.
After I wrote a really long query to do this I found the perfect soulution.
SELECT SUM(IF(meeting='1' && user_c=users.ID, 1,0)) as meeting_count FROM clients_closed_1 JOIN users
This query return as meeting_count the number of meeting which their value is '1'.
I didn't know I can do such thing until now, so I shared it here. I guess it can be helpull in the future.

select from table with result of another sql

Is it possible?
tag_table :
tag        postid
aa          22
bb          26
cc          28
post_table :
id          content
26            abc
28            cdf
22            fds
and I wanna select from post_table with result of search in tag_table
my script :
first
SELECT postid FROM `tag_table` WHERE `tag` LIKE '%aa%'
and put results in array then run a sql again
foreach ($postids as $key => $post_id) {
$sql .= "`id` = $post_id or";
}
and $sql is
SELECT * FROM `post_table` WHERE `id` = 22 or etc
and I wanna do it with one sql code
is it possible ?
You can use a subquery and IN statement like this:
SELECT *
FROM `post_table`
WHERE `id` IN (SELECT `postid`
FROM `tag_table`
WHERE `tag` LIKE '%aa%')

Categories