Find only the rows which have data on related table in YIi2 - yii2

I have two table: "Users" which contain user data, and "Posts" which contain user's post. Each user can have many posts.
Users
id
full_name
Posts
post_no
post_content
id_user
What I want to do is hide users which has no post, so I tried to join the tables in my search model:
public function search($params) {
$query = Users::find->joinWith(['posts']);
}
but unfortunately, users with no post still shown.

Use mysql WHERE NOT NULL syntax
$query = Users::find->joinWith(['posts'])->where(['not', ['posts.post_no' => null]]);
WHERE NOT NULL alternative syntax for Yii2:
->where(['IS NOT', 'posts.post_no', null]);
->where(['<>', 'posts.post_no', null]);
->having(['posts.post_no' => 'NOT NULL']);
Please Check the official documentation here:
http://www.yiiframework.com/doc-2.0/yii-db-query.html#where()-detail

Related

Laravel 7 how to perform a query sql with join in mongoDB

I have 2 databases(one in mySql and the other one in MongoDB) in my project and I need to perform a query like this
public function getPosts() {
$user = Auth::user();
$follow = DB::connection("mongodb")
->collection("followers")
->where("user_id", $user->id)->get();
/*$res = DB::select("
SELECT *
FROM posts
WHERE user_id = ? OR user_id IN
(SELECT user_id from $follows)
ORDER BY created_at DESC", [$user->id, $user->id]);
*/
return response()->json($res);
}
This is a query which returns the posts from the logged user and from people the user follow
The followers table (the one in MongoDB) contains "user_id" and "follows_id"
The commented line is the original query (every table in one single database on mySql
Thank you
Edit: I solved through a query in mongodb, then I edited the result to get an array which I incorporated into the sql query through orWhereIn Thank you for your answers :)
I don't think so... you may try a true multimodel database such as Oracle XE (it's free) to achieve your goal here...

INSERT INTO with joins?

I got trouble inserting data to a table that has joins to other tables, I've never done that before and the searchs I went through didn't help much.
I have an article page with a "comment" form that I want to send to my "comment" table. The "comment" table has joins with my "user" and "article" tables (to get which article the comment is part of, and which user sent it)
My comment table columns : comment_id, article_id, author_id, submitted_at, content
My user table columns :
user_id, username, password
My article table columns : article_id, preview_image, title, description, body, publishedAt, author_id
So this is what my query looks like :
public function setComment() {
try{
$stmt = $this->connection()->prepare("INSERT INTO comment (article_id, author_id, submitted_at, content) (SELECT comment.article_id, comment.author_id, submitted_at, content
FROM comment INNER JOIN user ON comment.author_id = user.user_id INNER JOIN article ON comment.article_id = article.article_id)");
$stmt->bindParam(':article_id', $_GET['id'], PDO::PARAM_INT);
$stmt->bindParam(':author_id', $_GET['id'], PDO::PARAM_INT);
$stmt->bindParam(':content', $_POST['comment'], PDO::PARAM_STR);
$stmt->execute();
} catch (PDOException $e){
echo $e->getMessage();
}
}
Well there is no error.... the only problem here is, when I submit my form all my rows in the comment table are duplicated by 2 lol... I just want to add a new row with the data in my bindParam()
So what's wrong?
BY THE WAY during my searchs I've seen people don't specify VALUE() when inserting to a table that has joins. So how do I insert the data that are in my bindParam()? That's weird
EDIT :: FOUND IT!! Actually I didn't need to use a SELECT at all
The correct query was :
INSERT INTO comment (article_id, author_id, submitted_at, content)
VALUES (:article_id, :author_id, NOW(), :content)
I had an error telling me "SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails"... So I thought I needed to join the tables or something but the actual problem was because in my query I bound the author_id to $_GET['id'] (that was 9)... and there is no user with the id of 9 in my user table. Shame on me
I used $_GET['id'] because I don't know how to properly get the id of the user sending the comment (and bindParam doesn't like it when I just use an integer)... with the session maybe idk, but that's a problem for another time

Laravel Eloquent Where Condition from 2 tables

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();

Wordpress/MySQL -> get post ids together with a count of total posts written by an author of a given post

In my Wordpress setup, each post has a post meta attached with meta_key=visitor_tracking_visitor_id, which is the post author id.
I'm trying to pull a list of posts from the Wordpress wp_posts table, together with a count of posts with status=publish for that given author id.
Tables
wp_posts
id|post_title|post_content|post_status ("publish" or "trash")
wp_postmeta
post_id (to join with wp_posts' id)|meta_key|meta_value
when meta_key=visitor_tracking_visitor_id the meta_value holds the author id
Example expected result:
|id|meta_value(author id)|count_of_posts_by_that_meta_value|
|1|1234|10|
|2|1234|10|
|3|5678|4|
I know how to pull the post info together with the author's id:
SELECT `id`, `post_title`, `post_content`, `post_status`, `meta_value` FROM `wp_posts`
LEFT JOIN wp_postmeta
ON `id` = `post_id`
WHERE `post_type` = 'post' AND `post_status` in ('trash','publish') AND `meta_key` = 'visitor_tracking_visitor_id'
How would I pull another field with the count of author's published posts using only SQL (without Wordpress functions)?
Thanks in advance for your help!
Why are you creating post meta for something that is already available in every post? Just get the author ID for the post get_the_author_id()
If you want lo list post links from an author, in the loop you can use
https://codex.wordpress.org/Function_Reference/the_author_posts_link
To get author or users post count you can use
https://codex.wordpress.org/Function_Reference/count_user_posts
No need to use SQL for this:
$args = array(
'meta_key' => 'visitor_tracking_visitor_id',
'meta_value_num' => 76, // The "author" ID,
'fields' => 'ids',
);
$query = new WP_Query($args);
$count = $query->found_posts;
Read more about WP_Query in the Codex.

Codeigniter active record join with 3 tables

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();