need help building one mysql query comparing a variable with two tables - php

I have built 2 queries that compares the $project_id variable to the 2 tables MEETING & MEETING_AGENDA shown in the flow diagram below:
+---------------------+
+------------+ | MEETING_AGENDA |
| MEETING | +---------------------+
+------------+ | meeting_agenda_id |
| meeting_id |----->| meeting_id |
$project_id --->| project_id | | meeting_agenda_name |
+------------+ +---------------------+
The logic behind this flow diagram is, I have stored a variable called $project_id which acts as the input. If the $project_id = MEETING.project_id then I need to store a list of the MEETING.meeting_id's. There are multiple duplicates of project_id's in MEETING resulting in an array of meeting_id's (just for clarification). If any of the MEETING.meeting_id's = MEETING_AGENDA.meeting_id then print meeting_agenda_name.
My messy attempt (which works) looks like this:
$project_id = $_SESSION['PROJECT_ID'];
$query1 =
"
SELECT meeting_id, meeting_project_id
FROM MEETING
WHERE project_id = $project_id
";
$result1 = mysqli_query($con, $query1) or die("Query error: " . mysqli_error($con));
while($row = mysqli_fetch_array($result1)){
$meeting_ids = $row['meeting_id'];
$query2 =
"
SELECT *
FROM MEEITNG_AGENDA
WHERE meeting_id = $meeting_ids
";
$result2 = mysqli_query($con, $query2) or die("Query error: " . mysqli_error($con));
while($row2 = mysqli_fetch_array($result2)){
echo $row2['meeting_agenda_name'] . "<br>"
}
}
I use 2 query's, I would like to clean this up into 1 query if possible. I have tried varies attempts at a single query but nothing has worked for me. Here is my latest attempt.
NEW QUERY:
$query =
"
SELECT MEETING.project_id, MEETING.meeting_id, MEETING_AGENDA.*
FROM MEETING
WHERE MEETING.project_id = $project_id
INNER JOIN MEETING.project_id
ON $project_id = MEETING.project_id
";
I apologize for my lack of mysql knowledge, but any help is appreciated.

You can get that information in a single query with the following:
SELECT m.project_id, m.meeting_id, ma.*
FROM MEETING m
INNER JOIN MEETING_AGENDA ma ON ma.meeting_id = m.meeting_id
WHERE m.project_id = $project_id

Related

Looping through a loop each result gives multiple incorrect results

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.

PHP MYSQL, two tables

I have two tables and i want to echo the total call count once each user logins:
Login
Firstname | Lastname | Login ID
------------------------------
Tyler | Durden | 3
Call Count
Name | Call Count | Open | GrandTotal
------------------------------
Tyler Durden| 100 | 33 | 133
i tried:
<?php
$result = mysqli_query($mysqli, "SELECT * FROM csvdata WHERE Name=".$_SESSION['firstname']. ' ' .$_SESSION['lastname']." ");
while($res = mysqli_fetch_array( $result )) {
echo $res['Open'].' Open Calls';
echo $res['GrandTotal'].' Grand Total Calls';
}
mysqli_close($mysqli);
?>
But its not working, i think i have to join the the two tables to get it to work. What do you think?
Assuming your Call Count table is actually called csvdata, you'll want to format your SQL request string a bit by adding single quotes around the WHERE name = part.
<?php
$result = mysqli_query($mysqli, "SELECT * FROM csvdata WHERE Name='".$_SESSION['firstname']. ' ' .$_SESSION['lastname']."' ");
while($res = mysqli_fetch_array( $result )) {
echo $res['Call Count'].' Call Count';
echo $res['Open'].' Open Calls';
echo $res['GrandTotal'].' Grand Total Calls';
}
mysqli_close($mysqli);
?>
Good practice would require that you use primary keys to facilitate joins between tables and make sure two users with the same name can be differenciated.
In that case you may want to consider replacing the Name column in your Call Count table for your loginID. This way you could get your name from the Login table (as shown below). Also, as bad as it is to have duplicated data like your user's name in both tables, you do not need your GrandTotal column since you can easily get the sum of CallCount and Open to get the exact same number. In the end, your query should look more like this (assuming your tables are called Login and CallCount).
<?php
$result = mysqli_query($mysqli, "SELECT l.FirstName, l.LastName, cc.CallCount, cc.Open, (cc.CallCount + cc.Open) AS GrandTotal FROM Login AS l JOIN CallCount AS cc ON l.LoginID = cc.LoginID WHERE l.FirstName LIKE \"".$_SESSION['firstname']."\" AND l.LastName LIKE \"".$_SESSION['lastname']."\"");
// ...
?>

Most Efficient way to MySQL Query inside query

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']];
}

how to select all data from mysql table where column is an array or single and my value match with one item of this array?

Please could someone help me? I want to select all values in mysql table where the column that i want to check get a value is mix with aingle or array of values....... So to be more clear I have a table to store all messages from many sender to one or many reciever....
my functions is
public static function find_messagesTo_by_user_id($mess_to=0) {
global $database;
$mess_to = $database->escape_value($mess_to);
$sql = "SELECT * FROM ".self::$table_name;
$sql .= " WHERE mess_to = '{$mess_to}'";
$sql .= " AND mess_deleted = 0";
$sql .= " ORDER BY mess_created_date DESC";
$result_array = parent::find_by_sql($sql);
return $resultrray;
}
So 'mess_to ' has array and single value .... they are only numbers Like (1, 15, 25 ,26 ,27 , array(1,25, 27) , 31, 42, .......)
Please, i break my head on it :)
I waiting for any help?
Building on #Maluchi's answer. Make sure your data looks like:
| mess_to |
+-----------------+
| ,123, |
| ,123,456,152,1, |
| ,456,567, |
| ,3, |
So surround each value in ,. then you can safely do:
WHERE `mess_to` LIKE "%,{$mess_to},%"
This ensures that $mess_to = 1 will match only the 2nd row, and not the 1st as well.
You could also denormalize your data and make a table to JOIN on.
If I'm reading it correctly, $mess_to is passed into the function and could contain either a single value or it could be passed in an array.
When matching multiple values, the SQL should be looking for a comma-separated list. The where clause needs to be IN the list rather than EQUAL to the list.
Try:
public static function find_messagesTo_by_user_id($mess_to=0) {
global $database;
$mess_to = $database->escape_value($mess_to);
$sql = "SELECT * FROM ".self::$table_name;
$sql .= " WHERE mess_to IN (" . implode(',', $mess_to) . ")";
$sql .= " AND mess_deleted = 0";
$sql .= " ORDER BY mess_created_date DESC";
$result_array = parent::find_by_sql($sql);
return $resultrray;
}
See this line in particular:
$sql .= " WHERE mess_to IN (" . implode(',', $mess_to) . ")";
Code edited with geomagas's comments! (Thank you geomagas!)
asuming your column is like this
| mess_to |
+---------+
| 1 |
| 1,2,3,4 |
| 2 |
| 3 |
you can use the LIKE operator:
$sql .= " WHERE mess_to LIKE '%{$mess_to}%'";
this will match every row where mess_to has the string value of $mess_to (your column data type should be string for this to work).

PHP/Smarty Nested array from DB

Ok guys I am trying to access a php/mysql db via a nested query.
eg. I have 2 tables 1) persons and 2) registration. I have a refferal id tab in registrations. So when a user logs in he should be able to see 4 levels of registrations done below his id.
Table structure
Registration
id | Registration ID | regtype | Upline ID | uid |FirstName |MiddleName | LastName Last etc
personal
id| uid | upline | fname | miname | lname | etc and lot of other details
Now i am doing it like this to get to the first level.
$tid=$_GET['tid'];
$con = mysql_connect("localhost","db","password");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
else
{
mysql_select_db("db", $con);
$resulta = mysql_query("SELECT * FROM personal WHERE id=$tid ");
$counta = mysql_num_rows($resulta);
while ($rowa = mysql_fetch_assoc($resulta)) {
$selid=$rowa['uid'];
$amount=$rowa['amountf'];
$plan=$rowa['planname'];
$resultfulla[] = $rowa;
}
$resultb = mysql_query("SELECT * FROM regtab WHERE regtab.upline=$selid " );
$countb = mysql_num_rows($resultb);
$rowz=array();
while ($rowb = mysql_fetch_assoc($resultb)) {
$rowz[] = $rowb;
}
Now i am able to get to one level but how do i cycle the second array and the arrays that will be produced later to get a tree structure. Or so....any help....
With the array rowz i am able to store the results of the 1st line regstration that i have done. Now using this array i need to find out how to get the second line registrations that have been done below array rowz.....
Join your queries and get the result.
$sql = "SELECT * FROM personal
LEFT JOIN regtab ON regtab.upline = personal.uid
WHERE personal .id=".$tid;
Get all the results in php.

Categories