I have a SELECT statement that provides me with a list of relevant IDs and company names that match the criteria. Here is the statement:
$result = mysqli_query($con,"SELECT a.OWNER_ID,b.ID, b.TITLE AS companyname FROM b_crm_act a INNER JOIN b_crm_company b ON a.OWNER_ID = b.ID");
while($row = mysqli_fetch_array($result))
{
echo "<tr>";
echo "<td>" . $row['ID'] . "</td>";
echo "<td>" . $row['companyname'] . "</td>";
echo "</tr>";
}
echo "</table>";
This lists all the IDs and company names. What I actually need is a list of IDs from b_crm_company that aren't in b_crm_act. I'm thinking I use NOT IN function but I've tried this and it's not listing anything.
Your help would be appreciated.
you can use LEFT JOIN on this
SELECT a.ID,
a.TITLE AS companyname
FROM b_crm_company a
LEFT JOIN b_crm_act b
ON a.ID = b.OWNER_ID // <== specify how the tables are linked
WHERE b.OWNER_ID IS NULL // <== a value of NULL when it doesn't exists
Not sure about your column names but this is how it looks like.
I don't know how efficient this is but have you tried using a NOT IN subquery?
SELECT ID,title FROM b_crm_company WHERE ID NOT IN( SELECT ID FROM b_crm_company INNER JOIN b_crm_act ON b_crm_act.OWNER_ID = b_crm_company.ID )
Related
I have a table A where several columns values should be replaced from corresponding id which are stored in table B as in this scheme:
TABLE_A
object_id desc_id_1 desc_id_2 desc_id_3 desc_id_4
zxy_34 9999 9567 5555 5556
TABLE_B
desc_id complete_desc
1234 ABCD
9999 ZYXW
9567 POTG
5555 YUNR
5556 LPVR
……..
……..
Final show than should be like that:
object comp_desc_1 comp_desc_2 comp_desc_3 comp_desc_4
zxy_34 ZYXW POTG YUNR LPVR
Is it possible?
At the moment tried something like that:
$sql="SELECT table_a.object_id, table_b.complete_desc
FROM table_a
LEFT JOIN table_b ON table_a.desc_id_1 =table_b.complete_desc";
It works ok using output this way:
echo "<table border='1'>
<tr>
<th>object</th>
<th>comp_desc_1 </th>
</tr>";
while($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td>" . $row['object_id '] . "</td>";
echo "<td>" . $row['desc_id_1 '] . "</td>";
echo "</tr>";
}
echo "</table>";
The problem is that don’t really know how to go further.
Adding another left join like that stop the script and make load a blank page:
$sql="SELECT table_a.object_id, table_b.complete_desc, table_b.complete_desc
FROM table_a
LEFT JOIN table_b ON table_a.desc_id_1 =table_b.complete_desc
LEFT JOIN table_b ON table_a.desc_id_2 =table_b.complete_desc ";
…..
echo "<table border='1'>
<tr>
<th>object</th>
<th>comp_desc_1 </th>
<th>comp_desc_2 </th>
</tr>";
while($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td>" . $row['object_id '] . "</td>";
echo "<td>" . $row['desc_id_1 '] . "</td>";
echo "<td>" . $row['desc_id_2'] . "</td>";
echo "</tr>";
}
echo "</table>";
Some one can help me?
You need to give each instance of table_b in your query an alias, otherwise it can't be known which one you are referring to. You also need to give the separate complete_desc values different names so they don't overwrite each other in the output array. Try something like this:
$sql="SELECT table_a.object_id, b1.complete_desc AS desc_id_1, b2.complete_desc AS desc_id_2
FROM table_a
LEFT JOIN table_b b1 ON table_a.desc_id_1 = b1.complete_desc
LEFT JOIN table_b b2 ON table_a.desc_id_2 = b2.complete_desc ";
You also need to remove the spaces in the array keys in these lines:
echo "<td>" . $row['object_id '] . "</td>";
echo "<td>" . $row['desc_id_1 '] . "</td>";
they should be:
echo "<td>" . $row['object_id'] . "</td>";
echo "<td>" . $row['desc_id_1'] . "</td>";
It is important that I urge you to restructure your "table_a" table. It just isn't set up to run clean, efficient, concise queries.
To normalize the structure, I recommend these columns:
object_id
desc_id
desc_order
Then the "pivot" query that you desire can be executed with just one LEFT JOIN.
SELECT object_id,
MAX(CASE WHEN desc_order = 1 THEN b.desc_id ELSE NULL END) AS desc_id1,
MAX(CASE WHEN desc_order = 2 THEN b.desc_id ELSE NULL END) AS desc_id2,
MAX(CASE WHEN desc_order = 3 THEN b.desc_id ELSE NULL END) AS desc_id3,
MAX(CASE WHEN desc_order = 4 THEN b.desc_id ELSE NULL END) AS desc_id4
FROM `table_a` a
LEFT JOIN `table_b` b ON a.desc_id = b.desc_id
GROUP BY `object_id`
SQLFIDDLE DEMO
I can only hope that you aren't too far in your project to make this adjustment, because it will set you up for a much easier time developing in the future. (Plus flexibility is improved -- if you decide you want more than 4 columns, you can seamlessly include 5 or more columns in the result set.
To get what you want, the JOINs need to be on the matching IDs, then get the respective description AFTER the join. If a given "ID" may not be present, you would need a LEFT-JOIN meaning all records from the LEFT side (first table/alias) regardless of a match on the right (second table/alias). Also, good to get into using aliases to simplify readability, especially on long table names, or when you need the same table multiple times such as this case...
select
a.Object_ID,
id1.complete_desc ID1Descript,
id2.complete_desc ID2Descript,
id3.complete_desc ID3Descript,
id4.complete_desc ID4Descript
from
Table_A a
LEFT JOIN Table_B id1
on a.desc_id_1 = id1.desc_id
LEFT JOIN Table_B id2
on a.desc_id_2 = id2.desc_id
LEFT JOIN Table_B id3
on a.desc_id_3 = id3.desc_id
LEFT JOIN Table_B id4
on a.desc_id_4 = id4.desc_id
Your join would never have a match such as ID Number compared to a description. You need the ID from the columns in your Table_A joined to the ID column of TableB, hence multiple "alias" references for alias "id1", "id2", "id3", "id4"...
BTW, may people frown on too many underscores for tables and/or columns. Get used to CamelCaseColumnNaming vs Using_Underscore_For_Columns. Just a suggestion...
I have these 3 tables in my DB:
Conductores: id_conductor, nombre_conductor
Trayectos: id_trayecto, Trayecto, Origen, Destino, Horas_conduccion
Viajes: id_viaje, id_conductor, id_trayecto, Salida, Llegada, Horas_conduccion, Disco, Semana
The table "Viajes" is the one in which I will insert the journeis of the truck drivers(conductor) every day, and I want to calculate the drive hours and rest hours for each truck driver in a table like this one:
The Code that I have to build this table is the following:
The connection to the data base obviously...
<?php
echo "<table border='1'>";
echo "<tr>";
echo "<td><b>Conductor</b></td>";
echo "<td><b>Posicion Actual</b></td>";
// (etc.........)
echo "<td><b>Descansos 11 H.</b></td>";
echo "</tr>";
$sql="SELECT * FROM conductores ";
$resultado=mysql_query($sql);
while($row=mysql_fetch_array($resultado)){
echo "<tr>";
echo "<td valign='top'>" . nl2br($row["nombre_conductor"]) . "</td>";
echo "<td></td>";
// (etc.........)
echo "</tr>";
}
I know how to calculate columns but just for one truck driver, for instance, if I want the Current Position (Posicion Actual) for driver 1, I'll do:
$result=mysql_query("SELECT Destino FROM trayectos WHERE (SELECT MAX(id_viaje) FROM viajes WHERE id_conductor=1)");
$row = mysql_fetch_array($result, MYSQL_ASSOC);
echo "Posición Actual = " . $row["Destino"];
Hours driving last week:
$result = mysql_query("SELECT SEC_TO_TIME (SUM( TIME_TO_SEC(Horas_conduccion))) as total FROM viajes WHERE id_conductor=1 AND semana=week(curdate())-1");
$row = mysql_fetch_array($result, MYSQL_ASSOC);
echo "horas semana anterior = " . $row["total"];
And so on with the rest.
So I want to do it automatically for each truck Driver, and cover the hole table.
Could you help me? I'm a little bit lost.
Get the ids of each conductor from the list of conductors and then pass it to the query and loop it.
$result=mysql_query("SELECT Destino FROM trayectos WHERE (SELECT MAX(id_viaje) FROM viajes WHERE id_conductor='.$conductor_id)");
You will need a combination of subqueries and joins to combine all these data into a single query.
SELECT c.*, t1.maxid, tr.Destino, t2.total FROM conductores c
LEFT JOIN (SELECT id_conductor, MAX(id_viaje) maxid FROM viajes GROUP BY id_conductor) t1 on c.id_conductor = t1.id_conductor
LEFT JOIN viajes v on t1.maxid=v.id_viaje
LEFT JOIN trayectos tr on tr.id_trayecto = v.id_trayecto
LEFT JOIN (SELECT id_conductor, SEC_TO_TIME (SUM( TIME_TO_SEC(Horas_conduccion))) as total
FROM viajes
GROUP BY id_conductor
WHERE semana=week(curdate())-1) t2 on c.id_conductor=t2.id_conductor
The 1st subquery retrieves the max(id_viaje) from viajes table by driver. Then I join again the viajes table to get the corresponding id_trayecto back and use that data to get the destination.
The 2nd subquery get the time summary by driver.
I'm trying to bring data from two different tables where there is a shared field:
in table1, I have many fields and one of them is the employee Position which is a number.
in table2 I have two fields: EmpPos(which is equal to Position in table1) and PosName.
Now, I want to print all employees' info from table1 but instead of printing Position(which is a number), I want to print its associated PosName from table2.
My following query is not working!
$sql ="SELECT * FROM table1, table2 WHERE table1.Position=table2.EmpPos";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
<tr>
<th>Name</th>
<th>Email</th>
<th>Position Name</th>
<th>phoneExt</th>
</tr>";
while($row = $result->fetch_assoc()) {
echo "<tr>";
echo "<td>" .$row['table1.FirstName'] ." " .$row['table1.LastName'] ."</td>";
echo "<td>" .$row['table1.Email'] ."</td>";
echo "<td>" .$row['table2.PosName'] ."</td>";
echo "<td>" .$row['table1.phoneExt'] ."</td>";
echo"</tr>";
}
Thanks in advance
The issue is you didn't define any relationship between the tables. So you should be using INNER or LEFT JOIN for this:
SELECT * FROM Table1 m INNER JOIN
Table2 k ON k.EmpPos = m.Position
Or the following should do:
SELECT * FROM Table1 m LEFT JOIN
Table2 k ON k.EmpPos = m.Position
As you have a foreign key (Shared field), then it's easy and obvious to use joins.
Using Inner JOIN
SELECT * FROM table1 tab1 INNER JOIN table2 tab2 ON tab1.position = tab2.EmpPos
I have three table in Mysql database MIITEM, DEMAND, MIILOC tables i want to select field from these three table display as a table .
i tried this but the join doesnt work for me
$sql = "SELECT demand.itemid, demand.qty, MIITEM.descr FROM demand
INNER JOIN MIITEM ON MIITEM.itemId = demand.itemid
WHERE demand.itemid = MIITEM.itemId
ORDER BY demand.itemid DESC";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "id: " . $row["itemid"]. " - demand: " . $row["qty"]. " - sales: " . $row["sales"]. "<br>";
}
} else {
echo "0 results";
}
$conn->close();
select dt.*, three_table.* from (
SELECT demand.itemid, demand.qty, MIITEM.descr FROM demand
INNER JOIN MIITEM ON MIITEM.itemId = demand.itemid
ORDER BY demand.itemid DESC) as dt inner join three_table on (dt.itemid = three_table.itemid)
you create the first select inner join 2 table wrap it with new select and inner join with the last table,
i didn't check the code... also you dont need the "where" you already doing inner join...
I'm currently making a table result based on PHP & mySQL, I encountered a problem where I would be pulling multiple data in tables with multiple condition, I also got error (mysqli_fetch_array() expects parameter 1 to be mysqli_result). Here are some of the codes:
<?php
include('mysql.php');
mysqli_select_db($con,"iiumsystem");
$id = $_GET['id'];
$sql = "SELECT stu_id, org_name, suv_id, stu_mark
FROM (SELECT * FROM student
INNER JOIN organization
ON org_name.stu_id = stu_id
WHERE (student.stu_id = '?' OR organization.stu_id ='?')) AS matches
INNER JOIN supervisor
ON suv_id.stu_id = stu_id
WHERE (student.stu_id = '?' OR supervisor.stu_id ='?')) AS matches
INNER JOIN mark
ON stu_mark.stu_id = stu_id
WHERE (student.stu_id = '?' OR mark.stu_id ='?')) AS matches";
$result = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($result))
{
echo "<tr>";
echo "<td class='result'>".$row['stu_id']."</td>";
echo "<td class='result'>".$row['suv_id']."</td>";
echo "<td class='result'>".$row['org_name']."</td>";
echo "<td class='result'>".$row['stu_mark']."</td>";
echo "</td>";
echo "</tr>";
}
echo "</tbody>";
echo "</table>";
mysqli_close($con);
?>
This clearly says you have some error in your sql query.
Try to print $sql query with parameters value in and run it into any mysql client i.e. phpmyadmin. It will show you correct query error.
SELECT stu_id, org_name, suv_id, stu_mark FROM
(SELECT * FROM student INNER JOIN organization ON org_name.stu_id = stu_id WHERE (student.stu_id = '?' OR organization.stu_id ='?'))
AS matches
INNER JOIN supervisor ON suv_id.stu_id = stu_id
WHERE (student.stu_id = '?' OR supervisor.stu_id ='?') AS matches
INNER JOIN mark
ON stu_mark.stu_id = stu_id
WHERE (student.stu_id = '?' OR mark.stu_id ='?') AS matches
Try this. You had two extra parantheses after the WHERE statements.
I'm not really sure what you're trying to do here, but all of those subqueries aren't going to help you.
SELECT student.stu_id, organization.org_name, supervisor.suv_id, mark.stu_mark
FROM student
INNER JOIN organization
ON organization.stu_id = student.stu_id
INNER JOIN supervisor
ON supervisor.stu_id = student.stu_id
INNER JOIN mark
ON mark.stu_id = student.stu_id
But I'm confused about your architecture here. From what I can make out of your query, it looks like there's a one-to-many relationship between student and each of supervisor, organization, and mark. I would expect the relationship to be:
student has one supervisor
student has one organization
student has many mark
In that case, student would have a org_id and suv_id field, while mark would have a stu_id field. You would then write the query as:
SELECT student.stu_id, organization.org_name, supervisor.suv_id
FROM student
LEFT JOIN organization
ON organization.org_id = student.org_id
LEFT JOIN supervisor
ON supervisor.sup_id = student.sup_id
And I'm not sure what you want to do with mark, since I assume you would have a lot of them. AVG(mark.stu_mark) maybe?