MySQL: AND operator doesn't work - php

I have chat database contains from three table (users,message,message_recipient)
and their relations here :
Database Design
the content of table is :
tabel users:
us_id username password
1 user1 pass1
2 user2 pass2
3 user3 pass3
table mesasage
id msg_body create_date creator_id
1 "Hi user2" --------- 1
2 "Hi user3 --------- 1
table message_recipient
id repient_id message_id is_read
1 2 1 0
2 3 2 0
my problem is when select the messages that user1 send to user2 the AND operator not working or there is bug with AND
the SQL Query :
SELECT message.id, message.msg_body,message.creator_id,message_recipient.recipient_id
FROM message,message_recipient
WHERE message.creator_id='1' AND message_recipient.recipient_id='2'
the output is:
id msg_body creator_id recipient_id
1 "Hi user2" 1 2
2 "Hi user3" 1 2

You need to use JOIN to do that:-
SELECT message.id, message.msg_body,message.creator_id,message_recipient.recipient_id
FROM message JOIN message_recipient ON message.id = message_recipient.message_id
WHERE message.creator_id='1' AND message_recipient.recipient_id='2'
Note:- When you are trying to get data from two or more tables then you need to use different types of Joins.
Reference:- https://www.w3schools.com/sql/sql_join.asp

You need to join them on message id. Try this:
SELECT m.id, m.msg_body, m.creator_id, mr.recipient_id
FROM message m
JOIN message_recipient mr on m.id=mr.id
WHERE m.creator_id='1' AND mr.recipient_id='2'

I added this in where clause message.id = message_recipient.message_id in your code and it's works
we can able to join multiple table using where clause .
SELECT message.id,
message.msg_body,message.creator_id,message_recipient.recipi‌​ent_id FROM
message,message_recipient WHERE message.id = message_recipient.message_id and
message.creator_id='1' AND message_recipient.recipient_id='2'

Related

join inbox and sent box table

I am creating message conversation script in PHP mysqli. I have two table inbox and sent box, this two table same columns I want to join this two table.and i want to get last message between two users.
inbox table
id from_id to_id msg sent_date
1 2 3 hi how are you? 2019-12-05 04:14:20
2 3 2 fine 2019-12-05 05:15:58
3 2 3 hi 2019-12-05 03:20:34
4 5 2 hi 2019-12-05 08:30:40
sentbox table
id from_id to_id msg sent_date
1 2 3 hi how are you? 2019-12-05 04:14:20
2 3 2 fine 2019-12-05 05:15:58
3 2 3 hi 2019-12-05 03:20:34
4 5 2 hi 2019-12-05 08:30:40
Here is my source code
<?php
if (isset($_SESSION['userid'])) {
$session_id = $_SESSION['userid'];
}
$sql = "SELECT *,
(SELECT username FROM users WHERE userid=from_id) AS from_username,
(SELECT username FROM users WHERE userid=to_id) AS to_username,
(SELECT username FROM users WHERE userid=?) AS my_username,
(SELECT profile_pic FROM users WHERE userid=from_id) AS from_profile_pic,
(SELECT profile_pic FROM users WHERE userid=to_id) AS to_profile_pic,
(SELECT profile_pic FROM users WHERE userid=?) AS my_profile_pic
FROM inbox WHERE from_id = ? OR to_id = ? ORDER BY id DESC";
if ($stmt = $con->prepare($sql)) {
$stmt->bind_param('iiii', $session_id, $session_id, $session_id, $session_id);
$stmt->execute();
}
What about this?
SELECT * from inbox i
inner join sentbox s on i.from_id = s.to_id
inner join users u on u.user_id = i.from_id
where i.from_id = 'your desired id here'
order by i.sent_date DESC limit 1;
I believe this would give you the latest communication between 2 users.
Having said that, it feels like it would be better to go with a simpler design where every communication is a transaction and you store it in a single table, with FROM and TO fields and the time of the communication. No need to do a JOIN between 2 tables here. You're duplicating data here.

Creating Message System in PHP

I m trying to create message system where I want to list down the users with whom one has interacted with recent chat on top I know this question is duplicate as well but i cant figure out where the problem is
Here is my message table structure
user_message table
msgID sentBy sentTo message sentTime
1 3 1 Hii B 1493306882
2 3 1 Hi A 1493309615
1 1 3 Hmm 1493306882
2 1 3 Yeah 1493309615
and the query i tried is
QUERY
SELECT * FROM user_message_status LEFT JOIN users ON user_message_status.userID=users.userID
LEFT JOIN user_message ON user_message_status.msgID=user_message.msgID WHERE user_message_status.userID='".$_SESSION['userid']."'
GROUP BY user_message_status.msgID ORDER BY user_message.msgID DESC
PROBLEM:
1) When userA send msg to userB, userA name is printed in chat list instead of recipient(userB)
2) The amount of msg sent or receive equals to the number of users are listed in the chat.
user_message_status: table
msgstatusID msgID userID box read readTime
1 1 3 outbox 0 0
2 1 1 inbox 0 0
This is status table to read unread messages or delete
First update the query to the below:
SELECT *
FROM user_message_status s
LEFT JOIN users u USING userID
LEFT JOIN user_message m USING msgID
WHERE s.userID='".$_SESSION['userid']."'
GROUP BY user_message_status.msgID
ORDER BY user_message.msgID DESC
Because both tables have the same column names, to make you sql shorter and neater, you can use the USING function
Both LEFT JOIN users ON user_message_status.userID=users.userID and LEFT JOIN user_message ON user_message_status.msgID=user_message.msgID was changed. We then renamed the tables to just a single letter so you don't have to write the entire table name.
Also why your userA is sent is because, your query will return, lets say I am id '3',
msgstatusID msgID userID box read readTime
1 1 3 outbox 0 0
So from the joins, the user_message will return
msgID sentBy sentTo message sentTime
1 3 1 Hii B 1493306882
1 1 3 Hmm 1493306882
So you would have to use an if statement or turnary operation for the name and say:
if (sentBy == $_SESSION['userid'])
$name = sentTo;
else
$name = sentBy;
OR
$name = (sentBy == $_SESSION['userid']) ? sentTo : sentBy;
Basically to show the proper name of who you are talking to, you need to first check which column name to use
AS for problem 2, if you want to limit the amount then you need to add more condition. Maybe you only want outbox so you need to put AND box = 'outbox'
The below sql should help you out
SELECT
s.msgId
, m.message
, (
SELECT CONCAT(firstName, ' ', lastName)
FROM users
WHERE userId = CASE WHEN m.sentTo = s.userId
THEN m.sentBy
ELSE m.sentTo END
) AS chatWith
, m.sentTime
, s.read
FROM user_message_status s
LEFT JOIN user_message m USING (msgID)
WHERE s.userID='".$_SESSION['userid']."'
ORDER BY m.msgID DESC
Remove LEFT JOIN users u USING userID because it will be sub queried
s.msgID // used for deleteing the chat conversation
m.sentBy, m.sentTo, m.message, m.sentTime // all important data for your messages

How to apply searching on two table using mysql

Hi i have two table one is parentlist and childlist.
I have have to apply searching on this table by parentname and childname. I have provided my table structure for better understanding, I have to apply searching on two different field of with different field name.
Fieldname is name in parentlist table and childname in childlist table.
I want below output if I type va then parentlist and childlist record should come in that query like below example. With this va Srting i have a
parentname varu123 and childname varu123 so I want these two record after executing the query.
This is the name of First table with fieldname
parentlist
............................................................
id name mobilenumber user_jid email
............................................................
1 varu123 123456 abc21 abc#gmail.com
2 abhishesk 123456 abc21 def#gmail.com
3 harsh 1234 def22 123#gmail.com
This is the name of Second table with fieldname
childlist
..........................................
id user_id childname Shoolname
...........................................
1 1 ram St.paul
2 1 raj St.xavier
3 2 varu123 St.paul
4 2 arun St.xavier
5 3 kapil St.paul
6 3 kamal St.xavier
I want this output: .
........................................................................................................
id name mobilenumber user_jid email childname Shoolname
..........................................................................................................
1 varu123 123456 abc21 abc#gmail.com ram,raj St.paul,St.xavier
2 abhishesk 123456 abc21 def#gmail.com varu123,arun St.paul,St.xavier
select pl.*, GROUP_CONCAT(cl.childname), GROUP_CONCAT(cl.Shoolname)
from parentlist as pl
inner join childlist as cl on pl.id=cl.user_id
where pl.name like '%va%' or cl.childname like '%va%'
use MySQL inner join or where :-
select * from parentlist inner join
childlist on parentlist.id=childlist.user_id
where childname='varu123' or parentlist.name='varu123'
use MySQL inner join or like :-
select * from parentlist inner join
childlist on parentlist.id=childlist.user_id
where childname like '%varu123%' or parentlist.name like '%varu123%'

Select from three tables

I have three tables where table_2 is the middle(connected) between table_1 and table_3
tables
table_id
...
...
table_rest
rest_id
table_id
...
rest
rest_id
...
...
And the query to select I use
SELECT m.table_id, table_name
FROM tables m
JOIN table_rest mr
ON m.table_id = mr.table_id
WHERE rest_id = '$rest_id'
What I need now is to join in this query another table reserv
id
...
status
To check if status is 0, 1,or 2 to not show me anything if there is no status this mean there is no record to show me. In other words this is resserved system where I show on screen few tables. If status is 0,1,2 thats mean the table is taken. If nothing is found for status this mean that there is no record for table and can be shown to user.
EDIT: Sample scenario
tables
table_id
1
2
3
4
5
rest
rest_id
1
2
table_rest
table_id | rest_id
1 2
2 2
3 2
4 2
5 2
So the query that is above will generate 5 tables for rest_id=2 and none for rest_id=1
So now I have another table
reserv
id | status
1 0
2 1
3 2
So in this table reserv currently are saved 3 tables. The idea is to show me other two whit id=4 and id=5 because they are not in table reserv and don't have any status.
Hope is a little bit more clear now.
You have to point from table reserv to which table is beign booked, let's call it reserv.table_id
SELECT m.table_id, table_name
FROM tables m
JOIN table_rest mr
ON m.table_id = mr.table_id
left join reserv
on reserv.table_id = m.id
WHERE rest_id = '$rest_id'
and reserv.status is null (*note)
*note use 'is' or 'is not' depending of your needs, as far as I read, first seems that you want !=, later that what you want is =
It's better if you provide sample data or sqlfiddle. Based on what I realize: Is this what you want:
select tables.table_id, rest.rest_id
from tables
left join table_rest on table_rest.table_id = tables.table_id
left join rest on rest.rest_id = table_rest.rest_id
where rest.rest_id = '$rest_id'
and tables.table_id not in (select id from reserv)

Return all the rows even the joined table has empty results

In my table 1 I have something like this
name | age
George 42
Bob 30
Ken 23
In my table 2, I have something like this, this is where i store votes for each person.
name | votes |
George 1
Ken 1
George 1
George 1
Ken 1
My goal is to combine the 2 tables, and return all the rows in table 1 even it doesn't exist in table 2.
Desire results:
name | age | total_votes
George 42 3
Bob 30 0
Ken 23 2
But instead I get:
name | age | total_votes
George 42 3
Ken 23 2
I have tried something like this
SELECT `table_1`.*, coalesce(COUNT(`table_2`.votes), 0) AS total_votes
FROM `table_1`
LEFT JOIN `table_2`
ON `table_1`.name = `table_2`.name
You can do one of these:
1) Use Right Join instead of current Left Join.
Or
2) Exchange table1 and table2 places in your join expression, like:
FROM table_2
LEFT JOIN table_1
Try this. This works in MS Access , I think this will work on your's too just convert the query to SQL:
SELECT Table1.name, First(Table1.age) AS age, Count(Table2.Votes) AS totalVotes
FROM Table1 LEFT JOIN Table2 ON Table1.name = Table2.name
GROUP BY Table1.name;
Left Join table1 to table2 so that all entry from table1 , even if its is corresponding data is null, will be included. GROUP BY your query by name so that votes will be counted by name .

Categories