I have a list of books titles that appear where a user can leave feedback.
I have 2 tables Books table & feedback table.
The tables are for a site where a user gives feedback on a book, once the user has left feedback for that book, I no longer want the book to appear in the book results for that user, there are many users that will be leaving feedback for the same book.
A book can have many feedback
I want to do somthing like if user already left a feedback in the feedback table, then that book they left feedback for should not appear in the results.
I'm not sure how to go about doing this?
my feedback table looks like this:
id
book_id
rating
feedback
user_id
my books table looks like this:
id
user_id
title
I am pulling the books results as follows.
$books = Books::where('user_id', $id)->get();
I need something that will check condition if the user has left feedback for the book yet, then don't show the books the user has already left feedback for in the results.
Just do a query that where the feedback is empty and if its empty it will have a result and if not of course it will not have a result so use if to ask the feedback if its empty
$feedback = Feedback::where('user_id', $id)->get();
$feed = '';
if(!empty($feedback->feedback)){
$feed = $feedback;
}
return view('yourview')->with('feed', $feed);
if you have join table you can do this also. on your upper controller put
use DB;
$feedback = DB::table('feedback as f')
->join('books as b', 'b.id', '=', 'f.book_id')
->join('user as u', 'user.id', '=', 'u.id')
->where('u.id',$id)
->select('u.*','f.*','b.*')->get();
$feed = '';
if(!empty($feedback->feedback)){
$feed = $feedback;
}
return view('yourview')->with('feed', $feed);
Assuming your have relation in your Books Modal like this
public function feedback(){
return $this->hasMany(Feedback::class,'book_id','id');
}
For getting all the books with user id $id which has atleast one feedback your query should be like this
$books = Books::where('user_id', $id)->has('feedback')->get();
If you need more filters you can use whereHas instead of has which will allow you to run more queries.
Update
To get Books that doesn't have feedbacks from user with userid $id will like this.
$books = Books:: whereDoesntHave('feedback',function($q) use($id){
$q->where('user_id',$id);
})->get();
But if you like to get all the books of a user with id $id and also he hasn't and also doesn't have any feedback from him
$books = Books::where('user_id', $id)-> whereDoesntHave('feedback',function($q) use($id){
$q->where('user_id',$id);
})->get();
Related
I have a table
'new_comments'
with fields
id,user_id,
title,
comment_description
I have another table named
'comments_upvote'
having
field user_id,
post_id,
likes
id of new_comments and post_id of comments_upvote table are same. we have to take those comments which have the most likes. how we fetch that data.
$ud = Comments_upvote::select('post_id')->groupby('post_id')-
>orderby(DB::raw('count(likes)'), 'desc')->get();
$postid = array();
foreach ($ud as $key => $value) {
$postid[] = $value->post_id;
}
$data = DB::table('new_comments')->whereIn('id',$postid)->get();
but the problem is that i have to count all likes whose value = 1 how can we do that.
If you showed us some code you'd get a more concrete answer, but here's a quick outline of what you need: define your relationships (make sure you use your custom foreign key), use whereHas, group by post_id count, and sort by count descending.
So I'm guessing you have at least two models NewComment and CommentUpvote (you should). In the NewComment define a 1:n relationship:
public function upvotes(){
$this->hasMany('App\CommentUpvote', 'post_id');
}
Then in your controller (again, guessing, since you didn't show any code):
$bestComments = NewComment::whereHas('upvotes', function($query){
$query->select('post_id', DB::raw('count(*) as total'))->groupBy('post_id')->orderBy('total', 'desc');
})->get();
Disclaimer: this is untested and off the top of my head, but should nugde you in the right direction.
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 3 tables,
user - contains user_id | username | fullname | email etcc
user_profile - contains entry_id |user_id| profile_image_id| user_location etcc
user_profile_images - contains image_id| user_id | file_path | file_thumb | date etcc
When a user sign's up, all the details go to the users table, the user_id is also added to the user_profile table with the rest set default as NULL till the user add's some profile info.
I have a query in model_users to get all user's data from these three table and it goes like this;
$this->db->where('users.user_id', $user_id)->select('*')->from('users');
$this->db->join('user_profile', 'user_profile.user_id = users.user_id', 'left');
$this->db->join('user_profile_images','user_profile_images.image_id = user_profile.profile_image_id','left');
It work's fine only when the profile_image_id field in user_profile is not null, that is when the user has uploaded a pic. In the case where the field is null, the user user_id is not returned even when all the other data are returned.
I can see why this is the case, as my join query requires the field profile_image_id but currently my way around it was to set profile_image_id in user_profile as 1(default), which is the default image and has image_id as 1 and user_id as 0 as it's the general default image. But i still can't get over the fact that i need to update that query to make it less of a hack.
Do you guys have any ideas?
Try
$this->db->select('*')->select('users.user_id')->from('users')
->join('user_profile', 'user_profile.user_id = users.user_id', 'LEFT')
->join('user_profile_images', 'user_profile_images.image_id = user_profile.profile_image_id', 'LEFT')
->group_by('users.user_id')
->where('users.user_id', $user_id);
$query = $this->db->get();
When using join for tables you need your columns in all joined tables to have unique names. Either you add column aliases by AS syntax or just retrieve the columns you need. In your case the error is most probably due to the fact that user_id exists in all three tables. Hence the result is like you experience. user_id is retrieved only for the last occurrence and that is if your user has uploaded an image. I would alter the query someting like:
$this->db->where('users.user_id', $user_id);
$this->db->select('users.*,user_profile.user_location,user_profile_images.filepath'); // and other fields of interest...
$this->db->from('users');
$this->db->group_by('users.user_id'); // very useful for not getting multiple rows/user
$this->db->join('user_profile', 'user_profile.user_id = users.user_id', 'left');
$this->db->join('user_profile_images','user_profile_images.image_id = user_profile.profile_image_id','left');
Try This one.
$this->db->select("*");
$this->db->from('table1');
$this->db->join('table2','table2.id1=table1.id1');
$this->db->join('table3','table3.id1=table1.id1');
$query = $this->db->get();
return $query->result();
I have two tables: Users and Groups
In my table "Users", there is a column called "ID" for all the user ids.
In my table "Groups" there is a column called "Participants", fields in this column are filled with all the user ids like this "PID_134,PID_489,PID_4784," - And there is a column "ID" that identifies a specific group.
Now what i want to do, i want to create a menu that shows all the users that are not yet in this particular group.
So i need to get all the user ids, that are not yet in the Participants column of a group with a particular ID.
It would be cool if there was a single mysql query for that - But any PHP + MySQL solutions are okay, too.
How does that work? Any guesses?
UPDATE:
i know, that's not code, but is there a way I could do something like this that would return me a list of all the users?
SELECT *
FROM users, groups
WHERE groups.participants NOT LIKE '%PID_'users.id'%' AND groups.id = 1;
Something like this. You just get rid of "PID_" part of ID.
SELECT * FROM [users] WHERE [id] NOT IN
(SELECT replace(id,'PID_','') FROM groups WHERE group_name='group1')
Group1 would be your variable - group id/name of menu that you've opened.
You can select from multiple tables as shown below:
SELECT * from users, groups WHERE users.id != groups.participants AND groups.id = 1;
This will list all users who are not in group id 1; A more elegant solution can be found by using joins, but this is simple and will do the trick.
I believe something like that should help:
SELECT * FROM users WHERE users.id NOT IN (SELECT groups.participants FROM groups)
But this works only if your DB is normalized. So for your case I see only PHP + MySQL solution. Not very elegant, but it does the job.
<?php
$participants_array = mysql_query("SELECT participants FROM groups");
$ids = array();
while ($participant = mysql_fetch_assoc($participants_array))
{
$id = explode(',', $participant['participant']);
foreach ($id as $instance)
{
if (!in_array($instance, $ids)) $ids[] = $instance;
}
}
$participants = implode(',', $ids);
$result = mysql_query("SELECT * FROM users WHERE id NOT IN ( $participants )");
But I highly recommend normalizing the database.
I have a join where i have a many to many relationship between categories and courses....I use multiple join in CodeIgniter with Active Record. My code looks like this:
$query = $this->db->select('*')
->from('subscriptions')
->where('subscriptions.user_id', $user_id)
->join('courses', 'courses.id=subscriptions.course_id')
->join('course_categories', 'course_categories.course_id=courses.id')
->join('categories', 'categories.id=course_categories.category_id')
->join('tutor_profiles', 'tutor_profiles.id=courses.tutor_id')
->get();
I have a problem retrieving multiple categories for 1 course...i want to have something like categories = array(JOIN RESULT). I mean i want to retrieve the results from the join of the categories in 1 sql variable that is an array and loop the results after.
How can I do this? Or do I need to make 2 queries?
You should try to serialize your result and save it in db