I have a MySQL DB that resembles the following:
uid suid
1 5
1 6
2 5
5 1
5 2
I am giving it a single unique "uid" via the POST method, call it 1. What I need to do is return all "suid" where $uid "has" suid AND suid (as uid) "has" $uid (as suid.) So, in the above example, the script should only return 5.
I know my first step is
"Select * FROM table Where uid = $uid"
then maybe I have to loop through the results and query the DB WHERE suid = $uid.
I do not know how to do the second query. Any suggestions?
One option here would be to self join, with the join condition being that uid in one table matches suid in the other table, and vice-versa for the suid in the first table.
SELECT
t1.suid
FROM yourTable t1
INNER JOIN yourTable t2
ON t1.uid = t2.suid AND
t1.suid = t2.uid
WHERE
t1.uid = 1
Before applying the WHERE clause, the above query would return two records:
uid | suid (uid not selected)
1 | 5
5 | 1
The WHERE clause then chooses the first record, which is what we want, using the uid parameter which you pass it.
Demo here:
Rextester
this is what I came up with:
$uid = $_POST["UID"];
$myquery = "SELECT * FROM Table WHERE uid = '$uid'";
$result = $conn->query($myquery);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$myquery2 = "SELECT * FROM Table WHERE uid = '" . $row['suid'] . "' AND suid = '$uid'";
$result2 = $conn->query($myquery2);
if ($result2->num_rows > 0) {
while($row = $result2->fetch_assoc()) {
echo $row["uid"].
"!##$";
}
}
}
}
$conn->close();
?>
I feel it is not pretty but it did the trick.
Related
I have been scratching my head for a very long time about this PHP code. I am trying to achieve something like
->Get each status
->Get each user in user's friends list
->Display status' from each user that is in the user's friends list
and repeat until there is no more. I have been looking for a solution for more a few days and it is really bugging me. Here is the code I tried:
EDIT: posted schema as requested
https://kjf-tech.net/files/schema.png
<?php
$connect = new MySQLi($DBhost,$DBuser,$DBpass,$DBname);
$querya = "SELECT * FROM statuses ORDER BY `id` DESC";
$result = mysqli_query($connect, $querya);
$ALLDATA = array();
$DBcon2 = new MySQLi($DBhost,$DBuser,$DBpass,$DBname);
if ($DBcon2->connect_errno) {
die("ERROR : -> ".$DBcon2->connect_error);
}
while ($record = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
array_push($ALLDATA, $record);
$queryb = "SELECT * FROM friendslist WHERE idOfPerson1='".$record['idOfUser']."' OR idOfPerson2='".$record['idOfUser']."' OR idOfPerson2='".$userRow['user_id']."' OR idOfPerson1='".$userRow['user_id']."' ORDER BY `id` DESC";
$result2 = mysqli_query($connect, $queryb);
$ALLDATA2 = array();
while ($record2 = mysqli_fetch_array($result2, MYSQLI_ASSOC)) {
array_push($ALLDATA2, $record2);
if($record['idOfUser'] == $userRow['user_id']) {
echo '<div>You Posted on '.$record['whenPosted'].'<br />'.$record['content'].'</div>';
}
elseif($record2['idOfPerson1'] == $userRow['user_id']) {
$query2 = $DBcon2->query("SELECT * FROM tbl_users WHERE user_id='".$record2['idOfPerson2']."'");
$userRow2=$query2->fetch_array();
echo '<div>'.$userRow2['username'].' Posted on '.$record['whenPosted'].'<br />'.$record['content'].'</div>';
}
elseif($record2['idOfPerson2'] == $userRow['user_id']) {
$query2 = $DBcon2->query("SELECT * FROM tbl_users WHERE user_id='".$record2['idOfPerson1']."'");
$userRow2=$query2->fetch_array();
echo '<div>'.$userRow2['username'].' Posted on '.$record['whenPosted'].'<br />'.$record['content'].'</div>';
}
}
mysqli_free_result($result2);
}
$DBcon2->close();
mysqli_free_result($result);
?>
Your schema looks good, but let's take another look at the relations. I'm going to rename some of the columns for convenience.
Users:
+- user_id
| user_name
|
|
| Friendships:
| fid
+- user_id
| friend_id --------+
| friendship_start |
| |
| |
| Statuses: |
| sid |
+- user_id ----------+
post_date
content
If you just wanted to find statuses of your friends, the query would look thus:
SELECT statuses.content
FROM friendships, statuses
WHERE friendship.user_id=? AND
friendships.friend_id = statuses.user_id
You would, of course, bind the appropriate user_id value when you ->prepare() the statement.
(See http://php.net/manual/en/mysqli.prepare.php for the proper way to do sql. You don't ever want to do something like mysql_query("select * from table where id=".$_POST['id']) because it's open to SQL injection)
Unfortunately, though, this does not include your own status in the query results. We'll have to do a little more work on the query...
SELECT statuses.content
FROM friendships, statuses
WHERE
( friends.user_id = ? AND
friends.friend_id = stuatuses.user_id )
OR
statuses.user_id = ?
ORDER BY statuses.post_date DESC
So far, so good... but we don't have the names nor the post date. The post date is easy, just add that to the select:
SELECT statuses.content, statuses.post_date
To add the name, we have to get data from Users also.
SELECT users.user_name, statuses.content, statuses.post_date
FROM users, friendships, statuses
WHERE
users.user_id = ? AND
(
( users.user_id = friendships.user_id AND
friendships.friend_id = statuses.user_id )
OR
statuses.user_id = users.user_id
)
ORDER BY statuses.post_date DESC
And there you have it; the database does all the work for you. No need for nested queries and such. This will just give you the simple list to print on your page. Please keep in mind that this is off the top of my head, so you may have to tweak it if I overlooked something.
i'm just learning PHP, and i have a question
Let just say, i have MySQL table "A"
Name | Job
--------|---------
Jynx | 1
Micah | 4
Nancy | 3
Turah | 1
And another table "B"
JobId | JobName
-------|-----------
1 | Lawyer
2 | Architec
3 | Farmer
4 | Mage
5 | Warrior
So supposedly in php i want to draw table that showed the content of table "A", but instead of displaying number at the "Job" colomn, they each display Job names from Table "B".
What is the most efficient way to do that?
For now, i just thinking of using
$conn = My database connect setting
$sql = "SELECT * FROM tableA ORDER BY Name";
$result = $conn->query($sql);
while($row = mysqli_fetch_assoc($result)) {
echo "<tr><td>". $row['Name'] ."</td><td>";
$sql2 = "SELECT * FROM tableB WHERE JobId=$row['Job']";
$result2 = $conn->query($sql2);
while($row2 = mysqli_fetch_assoc($result2)) {
echo "<td>". $row2['JobName'] ."</td></tr>;
}
}
But wouldn't it take a lot of calculating proccess if there is multiple similliar colomn with hundreed of rows?
Is there any more efficient way to do this?
Sorry for my bad english
Thank you for your attention.
A join is definitely the way to go here.
SELECT a.Name, b.JobName
FROM tableA a
JOIN tableB b on (a.Job = b.JobId)
ORDER BY a.Name
Well, it is not easy to learn about JOIN, no time for now, but i will get to learn it latter.
As for now, i just get the idea to just use ARRAY instead
So before i draw the main table, i assign the supportive table (Table B) into associative array
$sql = "SELECT * FROM tableB ORDER BY Id";
$result = $conn->query($sql);
while($row = mysqli_fetch_assoc($result)) {
$job[$row['JobId']] = $row['JobName'];
}
And at the main table
$sql = "SELECT * FROM tableA ORDER BY Name";
$result = $conn->query($sql);
while($row = mysqli_fetch_assoc($result)) {
echo "<tr><td>". $row['Name'] ."</td><td>". $job[$row['Job']];
}
I have two different tables of the following structure:
grouprel
id | userId | pupID | groupId
pupils
id | userId | fname | lname
pupId in groulrel is equal to id in pupils.
I want to fetch pupils from a different group and then order them by fname, lname.
Now I have two queries like this:
$q = "SELECT * FROM grouprel WHERE userid = ". $userid ." AND groupId = ". $_GET['id'] ."";
$r = mysqli_query($mysqli, $q);
while ($rows = mysqli_fetch_object($r)) {
$query = "SELECT id, fname, lname FROM pupils WHERE userid = ". $userid ." AND id = ". $rows->pupId ." AND status = 0 ORDER BY fname, lname";
$result = mysqli_query($mysqli, $query);
while($row = mysqli_fetch_object($result)) {
echo stuff...
}
}
This works, but it doesn't order the names alphabetically like I want to.
How could I fix this?
This is iterating over the first query:
while ($rows = mysqli_fetch_object($r)) {
And this iterates over each instance of the second query:
while($row = mysqli_fetch_object($result)) {
So if the first query returns 1,2,3, and each iteration of the second query returns A,B, then your output would be:
1 A
1 B
2 A
2 B
3 A
3 B
The second query is ordering by the ORDER BY clause you gave it. But you are ordering the entire output by the first query.
Ultimately, why do you need these separate queries at all? Executing a database query in a loop is almost always the wrong idea. It looks like all you need is one query with a simple JOIN. Guessing on your logic, something like this:
SELECT
pupils.id, pupils.fname, pupils.lname
FROM
pupils
INNER JOIN grouprel ON pupils.id = grouprel.pupId
WHERE
pupils.userid = ?
AND grouprel.groupId = ?
AND pupils.status = 0
ORDER BY
fname, lname
It may take a little tweaking to match exactly what you're looking for, but you can achieve your goal with a single query instead of multiple separate queries. Then the results of that query will be ordered the way you told MySQL to order them, instead of the way you told PHP to order them.
I have the following table, named "question".
I want a query that will retrieve the maximum QID from the table where I specify a Pid. Then I want to take the selected value and add 1 to it. I want this to work even if there is no value where Pid is for example 1 or 2.
For example if the max qid is 1 where pid is 1, I want a code to retrieve a 1 and add 1. If I in my query put "WHERE pid=2" and there is no pid=2 in my table, I want it to make qid=1.
I have this code to get the maximum qid-value but it doesn't work.
$qu = mysqli_query("SELECT max(qid) AS id FROM answer_det WHERE WHERE pid = '1' ");
$result = $mysqli->query($qu);
if ($result->num_rows > 0) {
while($row = $result->fetch_array()) {
echo $row['id'];
}
}
I think you should use ifnull
$qu = mysqli_query("SELECT ifnull(max(qid)+1, 1) AS id
FROM answer_det WHERE WHERE pid = '1' ");
In this way if you try a query for a pid that not exist you get the value 1 otherwise you get the value +1
I have a database structure something like the following:
Table A: PersonId, GroupId
Table B: GroupId, ParentGroupId
Given a PersonId, I want to find the Ids of all people in parent groups of that person's group.
First I select the ParentGroupId for the given PersonId, by joining with B. Then I do a while loop, selecting and recording the PersonId from A based on the GroupId returned in the previous search, and continue the loop by obtaining the next ParentGroupId from B.
Is this an efficient way to do this search, or is there an option that does not involve a while to "bubble up" in this manner?
(this is a simplified version of the actual scenario, changing the schema is not an option)
$sql = 'SELECT ParentGroupID FROM A WHERE PersonId = ' . $id;
$result = $db->query($sql);
$row = $db->fetch_array($result);
$parent_group = $row['ParentGroupId'];
if(!is_null($parent_group)) {
$parent_ids = array();
while($parent_group > 0) {
//is there a way to do this where I retrieve all managers <= lvl 6 at once, so I don't have to loop in order to 'tier up'?
$sql = 'SELECT ParentGroupID, PersonID
FROM B
INNER JOIN A on ParentGroupID = A.GroupID
WHERE ParentGroupID = ' . $parent_group;
$result = $db->query($sql);
$row = $db->fetch_array($result);
$parent_group = $row['ParentGroupID'];
$parent_ids[] = $row['PersonID'];
}
}
Combining your two queries into one would be more efficient:
$sql = 'SELECT ParentGroupID, PersonID
FROM B
INNER JOIN A on ParentGroupID = A.GroupID
WHERE ParentGroupID IN (
SELECT ParentGroupID FROM A WHERE ParentGroupID > 0
AND PersonId = ' . $id .')' ;