I have a table with the name message_system.
and structure of the table is as follow:
message_system => message_id(primary key)->sender_id->receiver_id->
message->time(current time stamp)
lets consider a $user_id = 1 and I want to select the row from the table
something like
select * from message_system where sender_id = $user_id or receiver_id = $user_id
and from the yielded result I want select only single result which has recently stored according to time stamp.
actually I want to select recent message from the message thread between two user..
edit 1:
I want to get recent message from the table with respect to each
unique pair of (user1_id and user2_id). Either it is(user1_id,
user2_id) or (user2_id, user1_id) usually user id of logged in user
would be on of the id and another is id of user who have been
messaged to current logged in user.
edit 2:
example:
lets consider user1 is logged in and he has messaged to user2. and later messaged to user3 and user4.
and those all messages are stored in the table and now i want to query such that it retrieves only recent message with user2,user3,user4 in user1 wall. not all their history
edit 3 :
query should return recent message of logged in user with user1 and recent message of logged in user user2 and user3 so on.
thank you for your time.
select * from message_system where sender_id = $user_id or receiver_id = $user_id
would translate in CodeIgniter in:
$this->db->where('sender_id', $user_id);
$this->db->or_where('receiver_id', $user_id);
$query = $this->db->get('message_system');
$row = $query->row();
If you want the most recent input, you could order by time, and if you know you only need one row, limit to 1:
$this->db->where('sender_id', $user_id);
$this->db->or_where('receiver_id', $user_id);
$this->db->order_by('time', 'desc');//order by time
$this->db->limit('1');//limit the query to only one row
$query = $this->db->get('message_system');
$row = $query->row();// get only first
UPDATE:
The solution above works if you want to find one entry corresponding to one given user.
If you want to find last entry for a given pair of users, thing would look like this if unknown who would be the sender and who would be te receiver:
$this->db->where_in('sender_id', array($user_id1, $user_id2));
$this->db->where_in('receiver_id', array($user_id1, $user_id2));
$this->db->order_by('time', 'desc');//order by time
$this->db->limit('1');//limit the query to only one row
$query = $this->db->get('message_system');
$row = $query->row();// get only first
And like this if you know exactly who is who:
$this->db->where('sender_id', $user_id1);
$this->db->where('receiver_id', $user_id2);
$this->db->order_by('time', 'desc');//order by time
$this->db->limit('1');//limit the query to only one row
$query = $this->db->get('message_system');
$row = $query->row();// get only first
With little bit modification of the table I have come up with an idea.
earlier my table structure was:
message_system => message_id(primary key)->sender_id->receiver_id->
message->time(current time stamp)
after modification:
message_system => message_id(primary key)->sender_id->receiver_id->
message->time(current time stamp)->unique_pair_key
unique_pair_key is to identify the message between two user uniquely and value would be something like this ($sender_id^2 + $receiver_id^2)
which is unique for given pair.
all messages between two particular user would be identify by this unique_pair_key.
so taking logged_in user as the reference, with respect to him only recent message with different user (if there any) should be shown (similar to stack overflow recent inbox message )and on clicking that particular message it should direct to their message thread.
model/model.php
public function get_notification($user_id)
{
$this->db->where("receiver_id",$user_id);
$this->db->where("sender_id",$user_id);
//because recent message would either be sent or received by logged in user
$this->db->select_max('message_id');
// latest message would have greatest value of id
$this->db->group_by('unique_pair_key');
$query = $this->db->get('message_system ');
//returns latest message_id with unique pair in which on of them is $userid.
}
above query only generates message id with that we can further query to get message
If you have any better solution please share with us.
Related
I have table A ( id - message - user_id ), I need to say if any user_id duplicated in table just bring last one that user had added:
My controller code (my wrong shut):
$duplicate = VerfiyRequest::where('user_id', '>' , 1)->first();
$VerfiyRequests = VerfiyRequest::latest()->get();
return view('backend.VerfiyRequest.index' , compact('VerfiyRequests'));
Use this to get the last record of each user by the latest id (incrementing primary key):
VerfiyRequest::whereIn('id', function ($query) {
$query
->from('verify_requests')
->select(DB::raw('MAX(id) as id'))
->groupBy('user_id');
})->get();
Explanation: the MAX(id) as id selects latest id of each user group, so the inner query returns latest record of each user.
Help with an SQL Query:
I want to get the last message of every conversation between client and helper. Based on same clientId lets say clientId = 1 but different helperId. What I am trying to achieve is build an inbox where last only last message of the conversation is available.
Here is the table structure.
Note: The clientId is known in the table everyother field is not known.
Please have a look at the table structure below:
You can do it this way:
$table = // table name
$clientId = // client's id
$query = "select * from ".$table." where `clientId`= '".$clientId."' group by `helperId` order by `id` desc";
This would give you the last conversation for the same client but with different helper.
I'm working something with mysql and php and I'm trying to achieve some result for learning purposes.
So what I'm trying is to make conversation messages system and I have following:
I have 2 tables, first conversation and second conversation_messages
First table conversation looks like following:
c_id, user_one, user_two
Second table conversation_messages looks like this:
m_id, text, date, created_by, status, c_id
So in messages table I set Conversation ID and when user click conversation to open it, url change to messages.php?c_id=1 or something like that... And that's fine, becouse I get c_id from url and so on.
My question is following:
Lets say I wan't to get all messages for conversation c_id = 1. How do I query trough table and get all messages for that conversation id. Also I need to query so it return results only if logged user is involved into conversation... So logged in user can see conversation messages only if he is person/user A (user_one) or user B(user_two). How do I do that and do I need to join tables. So what is the best way to do this.
So when logged in user type manually into url messages.php?c_id=3 if he is not involved into that conversation I don't want him to see it.
Sorry I'm new here and don't know how to format code properly or anything.
Thanks in advance.
You need to get the logged user id from a session and put into the query like that
SELECT * FROM conversation_message, conversation
WHERE conversation.c_id = $ID_OF_CONVERSATION
AND (user_one = $ID_LOGGED_USER OR user_two = $ID_LOGGED_USER)
AND conversation_message.c_id = conversation.c_id
In the broad strokes, if you want to add security to a certain endpoint, you need to allow or deny access after validating user input. In the example you gave, your user input is the c_id value of 3. In a simple PHP example, you could do something like this:
$user_id = $_SESSION['user_id'];
$can_access = false;
$convo_id = $_GET['c_id'];
$safe_id = mysql_real_escape_string( $convo_id );
$rli = mysql_query( "SELECT * FROM conversation WHERE c_id = {$safe_id}" );
if( mysql_num_rows( $rli ) ) {
$convo = mysql_fetch_object( $rli );
$can_access = $convo->user_one == $user_id || $convo->user_two == $user_id;
}
Notice in this example that I pulled the "logged in" user's id from the session, which assumes that you are using sessions. There are many different ways to create "logged in" user views, and that is somewhat outside the scope of this answer. The end result here is a boolean value variable $can_access which indicates whether or not the user can access the page. Assuming they can access the page, you could pull all the messages from the now validated conversation like so:
$rli = mysql_query("SELECT * FROM conversation_messages WHERE c_id = {$safe_id}");
$messages = array();
while( $message = mysql_fetch_object( $rli ) ) {
$messages[ $message->m_id ] = $message;
}
The above gives you a PHP array containing all the messages associated with the conversation. Hope this is enough to get you started.
I have a select statement:
SELECT id, content, name
FROM records
WHERE type = '1'
AND name = 'test';
Here's the output:
id content name
99708 10.6.252.41 server01.example.org
What I'd like to do is be able to get the id that is returned from the previous statement and USE the id as input into another statement (an UPDATE statement) that will increment the value of a single column in the same table.
An example UPDATE statement that I am wanting is:
update records SET hits = hits + 1 WHERE id = ID_FROM_SELECT;
Thanks in advance.
You can use user defined session variables for this if the SELECT is returning just one result:
SELECT #id:=id AS id, content, name
FROM records
WHERE type = '1'
AND name = 'test';
Then, on the same database session (connection), do the following:
UPDATE records
SET hits = hits + 1
WHERE id = #id;
I'm assuming you're doing something with the selected records in your app, and you're trying to save on performance by avoiding having to search for the record again in the UPDATE. Though, in that case, why not set the 'id' value as a parameter in code?
Obviously, if the SELECT is returning multiple records, this would best be done in code as I mentioned above, otherwise you're left with running the SELECT query again as a subquery:
UPDATE records
SET hits = hits + 1
WHERE id IN
(SELECT id
FROM records
WHERE type = '1'
AND name = 'test');
So, then, it makes more sense just to apply the same filter to the UPDATE instead:
UPDATE records
SET hits = hits + 1
WHERE type = '1'
AND name = 'test'
Probably this is not what you want to do.
First of all...If the query only returns 1 line, the solution provided by Marcus Adams works fine. But, if the query only returns one line, you dont need to preset the id in order to update. Just update it:
update records
set hits = hits + 1
where type = '1'
and name = 'test'
Second...If the query will not return only one record and you want to update all records returned with same values or calculations, the same code above will do what you need.
Third, if the query does not return just one record and you need to update each record returned with different value then you need to have a different approach.
I think you are not designing your system very well. If the request for update come from outside, you should have the id to be updated as a parameter of your request. For example something like:
<html>
<body>
Test
</body>
</html>
And in your update.php you have something like:
<?php
$id = $_GET['id'];
$sql = "update records set hits = hits + 1 where type = '1' and name = 'test' and id = $id";
?>
Of course, the picture I have is to small. Probably you have a reason to do this way or this is just an example. If you fill us up with more info we might be more helpful.
I have a messaging system (very basic) that has a table like this:
**MESSAGE_ID** **RUSER_ID** **SUSER_ID** **MESSAGE_DATA** **DATE**
RUSER is the receiving user, and SUSER is the sending user. If I wanted to output a query that would output a certain users messages, I would currently do:
Select * from PRIVATE_MESG where RUSER_ID=$USER_ID or SUSER_ID=$USER_ID
That would give me all message_id's that are associated with that USER_ID. What I would like, is to create a column that would produce only the ID associated with RUSER_ID or SUSER_ID associated with a specific user. I need it to choose the messages that RUSER_ID or SUSER_ID are equal to a USER_ID but only display the one that isn't USER_ID
I would then like to do a group by the output of that query.
Any help is greatly appreciated!
Thanks!
update I am not really looking for a message_id, I am just looking for a list of users who that person has written to or received from.
UPDATE
Just so everyone knows, I recieved the answer to this question perfectly! I tweaked it later on so that it would also display them by date from newest to oldest. I did this by spliting the DATETIME into DATE and TIME USING the DATE() and TIME() Function. Here was my final query:
SELECT
IF(RUSER_ID = $USER, SUSER_ID, RUSER_ID) as THE_OTHER_GUY, DATE(DATE) as DAY, TIME(DATE) as TIME
FROM PRIVATE_MESG
WHERE RUSER_ID = $USER
OR SUSER_ID = $USER;
group by THE_OTHER_GUY ORDER BY DAY DESC, TIME DESC
Hope this helps the next person!
You can query:
SELECT
*,
IF(RUSER_ID = $USER_ID, SUSER_ID, RUSER_ID) as THE_OTHER_GUY
FROM PRIVATE_MESG
WHERE RUSER_ID = $USER_ID
OR SUSER_ID = $USER_ID;
SELECT SUSER_ID FROM PRIVATE_MESG WHERE RUSER_ID=$USER_ID
UNION
SELECT RUSER_ID FROM PRIVATE_MESG WHERE SUSER_ID=$USER_ID
It retrieves:
- the list of user IDs who sent messages to $USER_ID
- the list of user IDs who received messages from $USER_ID
And UNION groups the 2 lists in a single result set.