Mysql Join two Id's to get there Usernames - php

Im trying to get in Array that contains the results from a MYSQL query.
I have 2 ids stored in the table hitlist user_id and mark_id
they need to join in the table users to retrieve there usernames that match there id's and in the future other variables.
i have this working in a weird way and was hopeing to get this working in a more efficent simple way similar to this
$Hitlists = $db->query("SELECT * FROM hitlist JOIN users ON hitlist.user_id = users.id AND hitlist.mark_id = users.id")->fetchAll();
This is the code i have that is working...for now it looks like it might give me problems later on.
<?php
$index = 0;
$Hitlists = array();
$st = $db->query("SELECT * FROM hitlist JOIN users ON hitlist.user_id = users.id")->fetchAll();
$sth = $db->query("SELECT * FROM hitlist JOIN users ON hitlist.mark_id = users.id")->fetchAll();
foreach($st as $id)
{
$Hitlists[] = $id;
}
foreach($sth as $id)
{
$Hitlists[$index]['markedby'] = $id['username'];
$Hitlists[$index]['mark_id'] = $id['mark_id'];
$index++;
}

The way you are joining the table is wrong. You can get the exact records you want, you need to join users table twice to get the username of each ID
SELECT a.*,
b.username User_name,
c.username mark_name
FROM hitlist a
INNER JOIN users b
ON a.user_id = b.id
INNER JOIN users c
ON a.mark_id = c.id
and you can access
$result['User_name']
$result['mark_name']

Related

PHP Retrieve information from five different tables with correct order

I develop a chat system where students and staff can exchange different messages. I have developed a database where we have five tables: the staff table, the student, the message and two mapping tables the staff_message and stu_message. These tables contain only the student/staff id and the message id.
My problem is that I cannot order the messages. I mean that I cannot figure out how can I make one SQL statement that will return all messages and be ordered by for example the ID. The code that I have made is this:
$qu = mysqli_query($con,"SELECT * FROM stu_message");
while($row7 = mysqli_fetch_assoc($qu)){
$que = mysqli_query($con, "SELECT * FROM student WHERE studentid =".$row7['stu_id']);
while($row8 = mysqli_fetch_assoc($que)) {
$username = $row8['username'];
}
$query3 = mysqli_query($con, "SELECT * FROM message WHERE id=".$row7['mid']);
while($row6 = mysqli_fetch_assoc($query3)) {
echo $row6['date']."<strong> ".$username."</strong> ".$row6['text']."<br>";
}
}
$query2 = mysqli_query($con, "SELECT * FROM staff_message");
while($row3 = mysqli_fetch_assoc($query2)){
$query = mysqli_query($con, "SELECT * FROM staff WHERE id =".$row3['staff_id']);
while($row5 = mysqli_fetch_assoc($query)) {
$username = $row5['username'];
}
$query3 = mysqli_query($con, "SELECT * FROM message WHERE id=".$row3['m_id']);
while($row6 = mysqli_fetch_assoc($query3)) {
echo $row6['date']."<strong> ".$username."</strong> ".$row6['text']."<br>";
}
}
?>
The result is different from that I want. To be more specific first are shown the messages from the students and then from the staff. My question is, is there any query that it can combine basically all these four tables in one and all messages will be shown in correct order? for example by the id?
Thank you in advance!
First, use JOIN to get the username corresponding to the stu_id or staff_id, and the text of the message, rather than separate queries.
Then use UNION to combine both queries into a single query, which you can then order with ORDER BY.
SELECT u.id, u.text, u.username
FROM (
SELECT s.username, m.text, m.id
FROM message AS m
JOIN stu_message AS sm ON m.id = sm.mid
JOIN student AS s ON s.id = sm.stu_id
UNION ALL
SELECT s.username, m.text, m.id
FROM message AS m
JOIN staff_message AS sm ON m.id = sm.m_id
JOIN staff AS s ON s.id = sm.staff_id
) AS u
ORDER BY u.id

Use INNER JOIN / JOIN for multiple query

What I have at the moment is to match the case from law_case, as in the database scheme below.
My code:
$query1 = "SELECT * FROM law_case WHERE id =?";
$query1vals = array($_GET['id']);
$ids = $adb->selectRecords($query1, $query1vals, false);
$a = $ids['case_type_id'];
$b = $ids['funding_pref'];
#
$query2 = "SELECT type_name FROM case_type WHERE id =?";
$query2vals = array($a);
$ids1 = $adb->selectRecords($query2, $query2vals, false);
$d = $ids1['type_name'];
#
$query3 = "SELECT * FROM expertise WHERE expertise_desc =?";
$query3vals = array($d);
$ids2 = $adb->selectRecords($query3, $query3vals, false);
$c = $ids2['id'];
#
$query4 = "SELECT * FROM individual_expertise WHERE expertise_id =?";
$query4vals = array($c);
$ids3 = $adb->selectRecords($query4, $query4vals, false);
$e = $ids3['individual_id'];
#
$query5 = "SELECT * FROM individual WHERE id =?";
$query5vals = array($e);
$ids4 = $adb->selectRecords($query5, $query5vals, false);
$f = $ids4['network_member_id'];
#
$query6 = "SELECT * FROM network_member WHERE id =?";
$query6vals = array($f);
$ids5 = $adb->selectRecords($query6, $query6vals, false);
And what it does is it only gets one network_member.
I want to use INNER JOIN, JOIN or LEFT JOIN and use a while looking to get the different member_name and the URL for each network_member or who's individual has the same expertise_id from the individual_expertise table.
I'm new to JOIN and tried this code but it doesn't work:
$sql = "SELECT member_name, url
FROM individual_expertise
LEFT JOIN individual
USING (individual_id)
LEFT JOIN network_member
USING (network_member_id)
WHERE expertise_id = ?";
$ids3 = $adb->selectRecords($sql, $query4vals, false);
echo $ids3['member_name'];
You need to get an overview of JOIN types. You have to build a query using INNER, LEFT, RIGHT, FULL joins depending on your logical requirements. You can assume that INNER join is equal to && or AND operators in conditional statements, I mean records must match in both tables.
While, LEFT join will return all rows from left table of join and matched rows from right table of join. And RIGHT is inverse of LEFT.
And FULL join is an example of || or OR in operators in conditional statements. I mean either a match in both tables.
So you have to join depending on logic you require.
See here
Do you know the difference between INNER JOIN and LEFT JOIN? I think you don't. You need an INNER JOIN here.
I think this is the right solution for your question:
SELECT
network_member.member_name,
network_member.url
FROM
network_member
INNER JOIN
individual ON individual.network_member_id = network_member.id
INNER JOIN
individual_expertise ON individual_expertise.individual_id = individual.id
WHERE
individual_expertise.expertise_id = ?

Inner/Left join with two different where clauses

i'm in the process of joining two tables together under two different conditions. For primary example, lets say I have the following nested query:
$Query = $DB->prepare("SELECT ID, Name FROM modifications
WHERE TYPE =1 & WFAbility = '0'");
$Query->execute();
$Query->bind_result($Mod_ID,$Mod_Name);
and this query:
$Query= $DB->prepare("SELECT `ModID` from `wfabilities` WHERE `WFID`=?");
$Query->bind_param();
$Query->execute();
$Query->bind_result();
while ($Query->fetch()){ }
Basically, I want to select all the elements where type is equal to one and Ability is equal to 0, this is to be selected from the modifications table.
I further need to select all the IDs from wfabilities, but transform them into the names located in modifications where WFID is equal to the results from another query.
Here is my current semi-working code.
$Get_ID = $DB->prepare("SELECT ID FROM warframes WHERE Name=?");
$Get_ID->bind_param('s',$_GET['Frame']);
$Get_ID->execute();
$Get_ID->bind_result($FrameID);
$Get_ID->fetch();
$Get_ID->close();
echo $FrameID;
$WF_Abilties = $DB->prepare("SELECT ModID FROM `wfabilities` WHERE WFID=?");
$WF_Abilties->bind_param('i',$FrameID);
$WF_Abilties->execute();
$WF_Abilties->bind_result($ModID);
$Mod_IDArr = array();
while ($WF_Abilties->fetch()){
$Mod_IDArr[] = $ModID;
}
print_r($Mod_IDArr);
$Ability_Name = array();
foreach ($Mod_IDArr AS $AbilityMods){
$WF_AbName = $DB->prepare("SELECT `Name` FROM `modifications` WHERE ID=?");
$WF_AbName->bind_param('i',$AbilityMods);
$WF_AbName->execute();
$WF_AbName->bind_result($Mod_Name);
$WF_AbName->fetch();
$Ability_Name[] = $Mod_Name;
}
print_r($Ability_Name);
See below:
SELECT ModID,
ID,
Name
FROM modifications M
LEFT JOIN wfabilities WF
ON WF.ModID = M.ID
WHERE TYPE =1 & WFAbility = '0'
To do this, you need to join your tables, I'm not quite sure what you are trying to do so you might have to give me more info, but here is my guess.
SELECT ID, Name, ModID
FROM modifications
JOIN wfabilities
ON WFID = ID
WHERE TYPE = '1'
AND WFAbility = '0'
In this version I am connecting the tables when WFID is equal if ID. You will have to tell me exactly what is supposed to be hooking to what in your requirements.
To learn more about joins and what they do, check this page out: MySQL Join
Edit:
After looking at your larger structure, I can see that you can do this:
SELECT modifications.Name FROM modifications
JOIN wfabilities on wfabilities.ModID = modifications.ID
JOIN warframes on warframes.ID = wfabilities.WFID
WHERE warframes.Name = 'the name you want'
This query will get you an array of the ability_names from the warframes name.
This is the query:
"SELECT A.ID, A.Name,B.ModID,C.Name
FROM modifications as A
LEFT JOIN wfabilities as B ON A.ID = B.WFID
LEFT JOIN warframes as C ON C.ID = B.WFID
WHERE A.TYPE =1 AND A.WFAbility = '0' AND C.Name = ?"

combining two mysql queries in php

I am creating a dashboard to keep me updated on call agent status.an agent will have multiple records in the log. I need to pull the most recent status from the agent log. The only way I have found is to query the agent table to pull the agents with status changes made today and then query the agent log table to pull the most recent status.
is there a way to combine the two queries.? Here are my queries
$sql_get_agents = "SELECT id FROM agent WHERE lastchange LIKE '{$today}%'";
if($dta = mysql_query($sql_get_agents)){
while($agent = mysql_fetch_assoc($dta)){
$curr_agent[] = $agent;
}
foreach($curr_agent as $agents_online){
$get_status_sql = "SELECT a.firstname,a.lastname,al.agentid,al.agent_statusid,s.id as statusid,s.status,MAX(al.datetime) as datetime FROM agent_log al
INNER JOIN agent a ON al.agentid = a.id
INNER JOIN agent_status s ON a.agent_statusid = s.id
WHERE al.agentid = '{$agents_online['id']}'";
if($dta2 = mysql_query($get_status_sql)){
while($agent_status = mysql_fetch_assoc($dta2)){
$curr_status[] = $agent_status;
}
}
}//end for each
return $curr_status;
}//end if
Why don't you join the 2 queries into one adding the WHERE lastchange LIKE '{$today}%' condition in the second query?
Using the IN clause should work :
"SELECT a.firstname,a.lastname,al.agentid,al.agent_statusid,s.id as statusid,s.status,MAX(al.datetime) as datetime FROM agent_log al
INNER JOIN agent a ON al.agentid = a.id
INNER JOIN agent_status s ON a.agent_statusid = s.id
WHERE al.agentid IN (SELECT id FROM agent WHERE lastchange LIKE '{$today}%');
You were close with what you have. This will get rid of the need to do both queries, or query in a loop.
edit: adding example code to loop over the results as well.
edit2: changed query.
$query = "SELECT
a.firstname,
a.lastname,
al.agentid,
al.agent_statusid,
s.id as statusid,
s.status,
MAX(al.datetime) as datetime
FROM agent a
LEFT JOIN agent_log al ON al.agentid = a.id
LEFT JOIN agent_status s ON a.agent_statusid = s.id
WHERE a.lastchange LIKE '{$today}%'";
$status = array();
$results = mysql_query( $query );
while( $agent = mysql_fetch_assoc( $results ) )
$status[] = $agent;
print_r( $status );

PHP And MYSQ help

ok here is my php and mysql code:
where it is bold i wanted to the the uid from the online table and if it in there
where online.uid = '' i needed so it put the uid in there.
$sql = ("select accounts.id,
accounts.tgid,
accounts.lastactivity,
cometchat_status.message,
cometchat_status.status,
**online.uid**
from friends_list join accounts
on friends_list.fid = accounts.id
left join cometchat_status
on accounts.id = cometchat_status.userid
where friends_list.status = '1'
and **online.uid = ''**
and friends_list.uid = '".mysql_real_escape_string($userid)."'
order by tgid asc");
#sledge identifies the problem in his comment above (I'm not sure why he didn't post an answer).
You are selecting a column from the online table, but you don't include it in your FROM clause. You have to query from a table in order to reference its columns in other parts of the query. For example:
$sql = ("select accounts.id,
accounts.tgid,
accounts.lastactivity,
cometchat_status.message,
cometchat_status.status,
online.uid
from friends_list
join accounts on friends_list.fid = accounts.id
join online on ( ??? )
left join cometchat_status
on accounts.id = cometchat_status.userid
where friends_list.status = '1'
and online.uid = ''
and friends_list.uid = '".mysql_real_escape_string($userid)."'
order by tgid asc");
You need to fill in the join condition, because there's not enough information in your original post to infer how the online table is related to other tables.
PS: Kudos for using mysql_real_escape_string().

Categories