I am creating a message service with Laravel.
I want to display recent messages from all based on time. This is what I am trying to implement
The following are my tables
message table
message_user table
I tried the following code
SELECT DISTINCT user_id,sender
FROM (
SELECT DISTINCT message_user.user_id, messages.sender, messages.created_at
FROM messages
JOIN message_user ON message_user.message_id=messages.id AND message_user.user_id=225
UNION
SELECT DISTINCT message_user.user_id, messages.sender, messages.created_at FROM messages
JOIN message_user ON message_user.message_id=messages.id AND messages.sender=225 AND message_user.user_id NOT IN (
SELECT DISTINCT messages.sender
FROM messages
JOIN message_user ON message_user.message_id=messages.id AND message_user.user_id=225
)
) mytable
ORDER BY created_at
The problem is that the output is not in the expected format (that is not sorted based on created_at)
Following is the corresponding Laravel code I have tried
$id = $request->user()->id;
$user = User::find($id);
$buddylist = $user->messages()->select(DB::raw('message_user.user_id,messages.sender,messages.created_at'));
$subquery = Message::select(DB::raw(' messages.sender'))->join('message_user','messages.id','=','message_user.message_id') ->where("message_user.user_id",'=',$request->user()->id);
$mybuddy = Message::selectRaw('message_user.user_id,messages.sender,messages.created_at')
->join('message_user','messages.id','=','message_user.message_id')
->where("messages.sender",'=',$request->user()->id)
->whereNotIn('message_user.user_id', $subquery)
->union( $buddylist)
->groupBy('sender')
->groupBy('user_id')
->orderBy('created_at','desc')
->get();
If you have another column named 'receiver_id' what you could do is:
$query="select * from messages WHERE sender_id='user_id' or receiver_id='user_id' ORDER BY created_at asc";
Related
So I have this query and display the value, the 'time' is integer, it is often updated by clicking and when it is updated I want the highest value si on the top of the list when page is refresh, but it's not, I wonder if the grouping affects the query?
$sql= "select * FROM message
where userid_to = '$UserLoggedIn' || userid_from = '$UserLoggedIn'
group by conversation_id
ORDER BY time DESC";
I think you should be doing the aggregation on conversations inside a subquery to find the most recent time for each conversation. Then join back to your message table to obtain the full message record. I'm not sure what went wrong with your ordering, but your current query is not deterministic.
SELECT m1.*
FROM message m1
INNER JOIN
(
SELECT conversation_id, MAX(time) AS max_time
FROM message
WHERE userid_to = '$UserLoggedIn' OR userid_from = '$UserLoggedIn'
GROUP BY conversation_id
) m2
ON m1.conversation_id = m2.conversation_id AND
m1.time = m2.max_time
ORDER BY
m1.time DESC;
I would try doing it this way:
SELECT *, MAX(time) as time
FROM message
WHERE userid_to = '$UserLoggedIn' OR userid_from = '$UserLoggedIn'
GROUP BY conversation_id;
I have a MySQL table from which I want to extract attendance information(Student Id, course/subject for attendance, date range,whether the student was present or not). I have written the following query:
SELECT
COUNT(a_id),
(
SELECT COUNT(*) FROM attendance
WHERE state = 'present'
AND `dater` BETWEEN '$a' AND '$b'
) AS Count,
stud_id
FROM attendance
WHERE
stud_id =(SELECT id FROM users WHERE NAME = '$stud')
Which is giving me the correct results, but when I change the student,its not giving me the correct count for the days recorded for present. Not mention that I have not yet added the course parameter into the query
The MySQL table is as follows:
I need help for the query to return the desired results(Count the accurate days present for each student, as well as adding the course parameter into the query so that the query will look for attendance records for a specific course, for a specific student, for a specified date range).
Looks like you want to seperate your queries:
Select (select count(*) from <database>.attendance where state = 'present' AND (dater between '$a' and '$b') AND name=(SELECT id FROM users WHERE NAME = '$stud')) as present, (select count(*) from <database>.attendance where state = 'absent' AND (dater between '$a' and '$b') AND name=(SELECT id FROM users WHERE NAME = '$stud')) as absent from <database>.attendance WHERE stud_id =(SELECT id FROM users WHERE NAME = '$stud');
try this :)
Resolved it using JOIN as follows:
SELECT u.id, a.stud_id, a.course_id, count(*) FROM attendance a
JOIN users u ON u.id=a.stud_id
JOIN courses c ON c.c_id=a.course_id
WHERE a.state='present' and dater between '2017-09-01' and '2017-09-14'
GROUP BY a.stud_id, a.course_id;
Thanks for your help.
I've been on this for a few hours without solution. I thought of laravel relationships but don't know how to pass a second condition because I need to relate with 3 tables. I'd like to use the query below in laravel.
SELECT
subscriptions.subscribed_to,
broadcasts. *,
FROM subscriptions
INNER JOIN broadcasts
WHERE subscriptions.subscriber = {$user_id}
AND (
SELECT COUNT(*) FROM seen_broadcasts
WHERE user_id = {$user_id}
AND broadcast_id = broadcasts.id
) = 0
ORDER BY broadcast.date DESC
There are 3 tables.
subscriptions: subscriber_id subscribes to broadcaster_id.
broadcasts: where broadcaster's message is saved.
seen_broadcast: where the information of subscribers are saved when they read a broadcast. This helps us provide detailed stats to broadcaster. user_id = subscriber_user_id, broadcast_id = broadcast_message_id
I want to be able to get broadcasts from all broadcaster that userA has subscribed to and have not seen.
The query above currently works outside laravel.
After much runarounds, I ended up with this:
$broadcast_result = DB::select( DB::raw("
SELECT
subscriptions.subscribed_to,
broadcasts.*
FROM subscriptions
INNER JOIN broadcasts
WHERE subscriptions.browser_agent_id = :subsc_id
AND broadcasts.user_id = subscriptions.subscribed_to
AND (
SELECT COUNT(*) FROM broadcasts_seen
WHERE broadcast_id = broadcasts.id
AND subscriber_id = subscriptions.subscriber_id
) = 0
ORDER BY broadcasts.date DESC LIMIT 1
"), array(
'subsc_id' => $subscriber->id
));
$broadcast_set = $broadcast_result[0];
Also add use DB; in the controller.
If there's a better way to do this, please share.
Please any one cal help me
My query is following
Column 'id' in where clause is ambiguous
SELECT u_profile.*, u_user.* FROM u_profile JOIN u_user ON u_profile.id = u_user.id WHERE id = '1' AND u_profile.id = '1'
from where id = 1 is coming I don't know please can help me some one.
You need to indicate the table name in your where clause, because SQL does not know what id is until you indicate the table to which it belongs.
Assuming you want to find both user_id and profile_id :
SELECT u_profile.*, u_user.* FROM u_profile
JOIN u_user ON u_profile.id = u_user.id
WHERE u.user_id = '1' AND u_profile.id = '1';
You can use like that in CodeIgniter For INNER JOIN:
$this->db->select();
$this->db->from('u_profile')->join('u_user', 'u_profile.id = u_user.id');
$this->db->where('u_user.id',1);
$this->db->where('u_profile.id',1);
For LEFT JOIN use this:
$this->db->select();
$this->db->from('u_profile')->join('u_user', 'u_profile.id = u_user.id','left');
$this->db->where('u_user.id',1);
$this->db->where('u_profile.id',1);
And Column 'id' in where clause is ambiguous means, you have two column with same in both table like id, so you need to use as u_user.id AND u_profile.id.
Originally my sql query works to check if there is pending timesheet/overtime ready for manager to review... now i added in on-call timesheets which is on a different table...
my previous sql query that worked but WITHOUT $ONCALL_TABLE...
list($qh, $num) = dbQuery("SELECT manager FROM $USER_TABLE WHERE username IN (SELECT DISTINCT uid FROM $TIMES_TABLE WHERE submitstatus=1 OR ot_status=1)");
now im trying to add the pending on-call timesheet to the same sql query but i keep getting errors... maybe someone can help me fix my syntax?:
list($qh, $num) = dbQuery("SELECT manager FROM $USER_TABLE WHERE username IN (SELECT DISTINCT $TIMES_TABLE.uid, $ONCALL_TABLE.uid FROM $TIMES_TABLE, $ONCALL_TABLE WHERE $TIMES_TABLE.submitstatus=1 OR $TIMES_TABLE.ot_status=1 OR $ONCALL_TABLE.submitstatus=1)");
ERROR I GET:
Can't perform query: Operand should contain 1 column(s)
The problem is in the subquery, but I would handle it using a union all:
SELECT manager
FROM $USER_TABLE
WHERE username IN (SELECT uid
from (select $TIMES_TABLE.uid
from $TIMES_TABLE
where $TIMES_TABLE.submitstatus=1 OR $TIMES_TABLE.ot_status=1
union all
select $ONCALL_TABLE.uid
from $ONCALL_TABLE
where $ONCALL_TABLE.submitstatus=1
) t
)
To be honest, though, the union all may interfere with with the use of indexes. This might perform better:
SELECT manager
FROM $USER_TABLE
WHERE username IN (select $TIMES_TABLE.uid
from $TIMES_TABLE
where $TIMES_TABLE.submitstatus=1 OR $TIMES_TABLE.ot_status=1
) or
username in (select $ONCALL_TABLE.uid
from $ONCALL_TABLE
where $ONCALL_TABLE.submitstatus=1
)