Having issues with SQL JOIN - php

Could someone help me make this better?
I am trying to get all rows from both tables where the sender and recipient matches the user_id and trashed has the value of 1;
This is what I've done. But my code is returning only one row, whereas there are at least two rows: one on each table.
Thanks.
$SQL = "SELECT *
FROM inbox
JOIN outbox
ON inbox.recipient = outbox.sender
AND
inbox.trashed = outbox.trashed
WHERE inbox.recipient = '$user_id'
AND
inbox.trashed = '1'"

Related

SQL - Delete row based on number of rows in another table

How would I go about deleting a row from the table 'subjects' that has a primary id 'subject_id' based on the number of rows in another table named 'replies' that uses a 'subject_id' column as a reference.
Example in pseudo code:
If ('subject' has less than 1 reply){
delete 'subject'}
I don't know much about SQL triggers so I have no clue if I would be able to incorporate this directly in the database or if I'd have to write some PHP code to handle this...
To delete any subjects that have had no replies, this query should do the trick:
DELETE s.* FROM subjects AS s
WHERE NOT EXISTS
(
SELECT r.subject_id
FROM replies AS r
WHERE r.subject_id = s.subject_id
);
Demo: DB Fiddle Example
One of the MySQL gurus will need to weigh in on whether or not you can do this directly, but in PHP you could...
$query = "SELECT subject_id FROM subjects WHERE subject='test'";
$return = mysqli_query($mysqli, $query);
$id = mysqli_fetch_assoc($return);
$query = "SELECT reply_id FROM replies WHERE subject_id='".$id[0]."'";
$return = mysqli_query($mysqli, $query);
if(mysqli_num_rows($return) < 1){
$query = "DELETE FROM subjects WHERE subject_id='1'";
$return = mysqli_query($mysqli, $query);
}
This example assumes the "subject" is unique. In other words, SELECTing WHERE subject='test' will only ever return one subject_id. If you were doing this as a periodic cleaning, you would grab all the subject_id values (no WHERE clause) and loop through them to remove them if no replies.
You can achieve this in one query by selecting all (unique) subject-ids from the replies table, and delete all subjects that doesn't have a reply in there. Using SELECT DISTINCT, you don't get the IDs more than once (if a subject has more than one reply), so you don't get unnecessary data.
DELETE FROM subjects
WHERE subject_id NOT IN (SELECT DISTINCT subject_id FROM replies)
Any subject that doesn't have a reply should be deleted!
So you want to delete all subjects with no replies:
DELETE FROM subjects WHERE subject_id NOT IN
(SELECT subject_id FROM replies);
I think this is what you want...

Relational table query gives me a null value in the field 'id' in table

I am creating a query and I used the LEFT JOIN to join two tables. But I'm having trouble in getting the fb_id value from the table, it gives me an empty result. Here is my code:
$sql = "SELECT * FROM tblfeedback a LEFT JOIN tblreply b ON a.fb_id = b.fb_id WHERE a.fb_status = 1 ORDER BY a.fb_id DESC";
$res = $con->query($sql);
....
....
The query above would give me a result like this :
I think that's why I don't get the fb_id value is because the last column is null. How do I get the value of fb_id from the first column? Thanks. I am really having trouble with this. I hope someone can enlightened my mind.
You should give an alias to the column in the parent table, because the column names are the same in both tables. When fetch_assoc() fills in $row['fb_id'], it gets the last one in the result row, which can be NULL because it comes from the second table.
SELECT a.fb_id AS a_id, a.*, b.*
FROM tblfeedback a
LEFT JOIN tblreply b ON a.fb_id = b.fb_id
WHERE a.fb_status = 1
ORDER BY a_id DESC
Then you can access $row['a_id'] to get this column.
More generally, I recommend against using SELECT *. Just select the columns you actually need. So you can select a.fb_id without selecting b.fb_id, and it will always be filled in.
Because you are using a left join, the 2 rows in your result set image are the rows from tblfeedback whose fb_id were not found in tblreply. We know this is true because all the tblreply columns in the result set are null.
With that said, its not real clear what you are asking for. If you are asking how you access the tblfeedback.fd_id column from your query via php, you can use the fetch_array method and use the 0 index.
$sql = "SELECT * FROM tblfeedback a LEFT JOIN tblreply b ON a.fb_id = b.fb_id WHERE a.fb_status = 1 ORDER BY a.fb_id DESC";
$res = $con->query($sql);
while($row = $res->fetch_array()) {
echo "fb_id: " . $row[0] . "<br>";
}

php: for each record in one mysql table, display all the records from a 2nd table

I have 2 tables, one with email addresses, and one with a number of rows per email address:
Table 1:
1#gmail.com
2#gmail.com
etc
Table 2:
1#gmail.com,value111,value112,value113
1#gmail.com,value121,value122,value123
2#gmail.com,value211,value212,value213
etc.
I want to send each of the email addresses their values, so I get the email:
$query = "SELECT email FROM email_table";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
$email = $row['email'];
and then, I need to get the values for each email.
I tried using foreach but apparently not in a correct way
Can anybody help?
Many thanks!
You are wanting to do a JOIN. So your query will look like this:
SELECT * FROM table2 JOIN table1 ON (table2.email = table1.email);
Coding Horror has a great explanation of all the join types between the tables.
$query = "SELECT * FROM email_table AS table1 LEFT JOIN table2 ON table2.email = table1.email";
--edit--
after clarification, you want to get the info from table 2 attached to the email address in table 1 and send an email to table 1...
$query = "SELECT table1.email, table2.* FROM email_table AS table1 LEFT JOIN table2 ON table2.email = table1.email";
Your result here is the email field from table 1 with all information from table 2 joined on the same email address. You don't need both emails returned here so in your field list, put something like this instead of table2.*:
SELECT table1.email, table2.field1, table2.field2, table2.field3
Then you can use PHP's mail to send to the email you get from table1.

Display only unique entries in mysql

I am building a mysql based chat application.
My database schema has the following tables,
Users Messages
================= =================
id id
screen_name message
from
to
timestamp
The from and to fields on the messages table contain the id's of the users that sent and received each message.
I am trying to display all messages between a user ($id) and one of their friends ($friend). My query is the following:
$query = "SELECT messages.* , users.screen_name FROM users CROSS JOIN messages ";
$query .= "ON ( messages.to = $id AND messages.from = $friend ) ";
$query .= "OR ( messages.to = $friend AND messages.from = $id )";
The problem is that every message is twice in the result table.
I tried using DISTINCT but it either doesn't work in this scenario or I used it wrong.
What should my query be in order to have each message between the two users only once?
Something like this should do the trick:
SELECT
messages.*,
users_from.screen_name AS from_screen_name,
users_to.screen_name AS to_screen_name
FROM
messages
JOIN users AS users_from ON messages.from = users_from.id
JOIN users AS users_to ON messages.to = users_to.id
WHERE
(messages.to = $id AND messages.from = $friend)
OR ( messages.to = $friend AND messages.from = $id)
What this does is joing the "users" table twice, once on the "to" column and the second time on the "from" column.
#Travesty3 has already suggested that the DISTINCT keyword will only exclude duplicate rows where all fields are equal to another row. Therefore, the DISTINCT keyword is not the way to go here.
What you can do, however, is to simply GROUP BY messages.id in order to get only one row per message ID (there is no guarantee, however, as to which of the two rows will be excluded).

What is the query statement to write in order to solve the followin database problem?

I have the following 3 tables in the database.
Programs_Table
Program_ID (Primary Key)
Start_Date
End_Date
IsCompleted
IsGoalsMet
Program_type_ID
Programs_Type_Table(different types of programs, supports a dropdown list in the form)
Program_type_ID (Primary Key)
Program_name
Program_description
Client_Program_Table
Client_ID (primary key)
Program_ID (primary key)
What is the best way to find out how many clients are in a specific program (program type)?
Would the following SQL statement be the best way, or even plausible?
SELECT Client_ID FROM Client_Program_Table
INNER JOIN Programs_Table
ON Client_Program_Table.Program_ID = Programs_Table.Program_ID
WHERE Programs_Table.Program_type_ID = "x"
where "x" is the Program_type_ID of the specific program we're interested in.
OR is the following a better way?
$result = mysql_query("SELECT Program_ID FROM Programs_Table
WHERE Program_type_ID = 'x'");
$row = mysql_fetch_assoc($result);
$ProgramID = $row['Program_ID'];
$result = mysql_query("SELECT * FROM Client_Program_Table
WHERE Program_ID = '$ProgramID'");
mysql_num_rows($result) // returns how many rows of clients we pulled.
Thank you in advance, please excuse my inexperience and any mistakes that I've made.
Here is how you can do it:
<?php
// always initialize a variable
$number_of_clients = 0;
// escape the string which will go in an SQL query
// to protect yourself from SQL injection
$program_type_id = mysql_real_escape_string('x');
// build a query, which will count how many clients
// belong to that program and put the value on the temporary colum "num_clients"
$query = "SELECT COUNT(*) `num_clients` FROM `Client_Program_Table` `cpt`
INNER JOIN `Programs_Table` `pt`
ON `cpt`.`Program_ID` = `pt`.`Program_ID`
AND `pt`.`Program_type_ID` = '$program_type_id'";
// execute the query
$result = mysql_query($query);
// check if the query executed correctly
// and returned at least a record
if(is_resource($result) && mysql_num_rows($result) > 0){
// turn the query result into an associative array
$row = mysql_fetch_assoc($result);
// get the value of the "num_clients" temporary created column
// and typecast it to an intiger so you can always be safe to use it later on
$number_of_clients = (int) $row['num_clients'];
} else{
// query did not return a record, so we have no clients on that program
$number_of_clients = 0;
}
?>
If you want to know how many clients are involved in a program, you'd rather want to use COUNT( * ). MySQL (with MyISAM) and SQL Server have a fast way to retrieve the total number of lines. Using a SELECT(*), then mysql_num_rows leads to unnecessary memory ressources and computing time. To me, this is the fastest, though not the "cleanest" way to write the query you want:
SELECT
COUNT(*)
FROM
Client_Program_Table
WHERE
Program_ID IN
(
SELECT
Program_ID
FROM
Programs_Table
WHERE
Program_type_ID = 'azerty'
)
Why is that?
Using JOIN make queries more readable, but subqueries often prove to be computed faster.
This returns a count of the clients in a specific program type (x):
SELECT COUNT(cpt.Client_ID), cpt.Program_ID
FROM Client_Program_Table cpt
INNER JOIN Programs_Table pt ON cpt.Program_ID=pt.Program_ID
WHERE pt.Program_type_ID = "x"
GROUP BY cpt.Program_ID

Categories