Laravel 5 - compare query from one table to another query - php

I have two tables: a relationship table and a users table.
Relationship table looks like: 'user_one_id', 'user_two_id', 'status', 'action_user_id'.
Users table looks like: 'id', 'username'.
I would like to query the relationship table first and return an array of all the rows where the 'status' column = 0.
Then I would like to query the users table and return an array of ids and usernames where 'user_one_id' matches 'id'.
My code so far:
public function viewRequests()
{
$currentUser = JWTAuth::parseToken()->authenticate();
$friendRequests = DB::table('relationships')
->where('user_two_id', '=', $currentUser->id)
->where('status', '=', '0')
->get();
$requestWithUsername = DB::table('users')
->where('id', '=', $friendRequests->user_one_id)
->get();
return $requestWithUsername;
}
It's not working and I'm not sure what method is easiest to reach my desired output. How can I change these queries?
EDIT:
After reviewing the response, this is the working code:
$friendRequests = DB::table('users')
->select('users.id','users.username')
->join('relationships', 'relationships.user_one_id','=','users.id')
->where('relationships.status','=',0)
->where('relationships.user_two_id', '=', $currentUser->id)
->get();

Your SQL seems to be this:
SELECT id, username
FROM users
JOIN relationships
ON relationships.user_one_id = id
WHERE relationships.status = 0
Then the Laravel way:
DB::table('users')
->select('id','username')
->join('relationships', 'relationships.user_one_id','=','id')
->where('relationships.status','=',0)
->get();

Related

How to store a group of fields in a variable after a ->get() query

The following is my query which may output more than one row. I need to store the user_id field in each row in the $send_user_id variable below, so that I will use a foreach loop in the blade. I'm currently receiving (Trying to get property of non-object) error.
$j_request = DB::table('grpusrs')
->join('users', 'users.id', '=', 'grpusrs.user_id')
->join('groups', 'grpusrs.group_id', '=', 'groups.id')
->where('groups.owner_id', $user_id)
->where('grpusrs.join_request', 1)
->get();
$send_user_id = $j_request->user_id;
Also this query joins two tables, so how do I specify the table that has the required field? (i.e. I want the user_id that is in the 'Grpusrs' table not in the 'Groups' table)
If you need to retrieve multiple user_id you can loop through $j_request object and collect every user_id inside an array.
$j_request = DB::table('grpusrs')
->join('users', 'users.id', '=', 'grpusrs.user_id')
->join('groups', 'grpusrs.group_id', '=', 'groups.id')
->where('groups.owner_id', $user_id)
->where('grpusrs.join_request', 1)
->select('users.*', 'contacts.phone', 'orders.price')
->get();
$send_user_id = [];
$j_request->each(function($item) use ($send_use_id){
$send_user_id[] = $item->user_id;
});
If you only need one user_id you should be more "precisely" in your query (get just one record). After that, you can get user_id simply with $j_request->user_id

How to make two Laravel Eloquent queries into a single one (so I hit the database once instead of 2 times)

Say I have 3 tables in my database.
'my_recipe', 'my_inventory' and 'ingredient'.
The 'my_recipe' table stores a list of raw_id's based on the 'ingredient' table and the 'quantity' need for the recipe. The 'my_inventory' table stores a list of raw_id's and 'have_quantity'.
So let's take a look at what I currently have at the moment. I have the following 2 queries:
First Query:
$recipe = DB::table('my_recipe as tA')
->leftJoin('ingredient as tB', 'tA.raw_id', '=', 'tB.raw_id')
->select('tA.user as user', 'tA.raw_id as raw_id', 'tA.quantity as quantity',
'tB.ingredient_name as ingredient_name')
->where('user', '=', $user)
->where('raw_id', '=', $raw_id)
->get();
Second Query:
$inventory = DB::table('my_inventory as tA')
->leftJoin('ingredient as tB', 'tA.raw_id', '=', 'tB.raw_id')
->select('tA.user as user', 'tA.have_quantity as have_quantity',
'tB.ingredient_name as ingredient_name')
->where('user', '=', $user)
->get();
The first query returns results that look something like this:
{"user":"jack","raw_id":"853","quantity":2,"ingredient_name":"apple"},
{"user":"jack","raw_id":"853","quantity":4,"ingredient_name":"peach"}
The second query returns results that look something like this:
{"user":"jack","have_quantity":30,"ingredient_name":"apple"},
{"user":"jack","have_quantity":20,"ingredient_name":"apple"},
{"user":"jack","have_quantity":10,"ingredient_name":"apple"},
{"user":"jack","have_quantity":1,"ingredient_name":"peach"},
{"user":"jack","have_quantity":1,"ingredient_name":"peach"}
Notice in the second query results I have to get the sum of the ingredients based on the 'ingredient_name' for my ideal output.
How can I get my ideal output in a single query?
My ideal output would look something like this:
{"user":"jack","raw_id":"853","quantity":2,"ingredient_name":"apple","have_quantity":60},
{"user":"jack","raw_id":"853","quantity":4,"ingredient_name":"peach","have_quantity":2}
It's basically the results of the first query with 'have_quantity' totals from the second query.
EDIT:
my_recipe Model:
'user', 'raw_id', 'quantity'
my_inventory Model:
'user', 'raw_id', 'have_quantity'
ingredient Model:
'raw_id', 'ingredient_name'
Note: In the ingredient model there can be rows with the same 'ingredient_name' but have different 'raw_id'.
Based on our chat conversation I managed to get some extra information on the table structure and what was needed to do to get the wanted results.
For those interested the information can be found here
Anyway I ended up creating the query like this:
SELECT
my_recipe.user AS user,
my_recipe.raw_id AS raw_id,
my_recipe.quantity AS quantity,
ingredient.ingredient_name AS ingredient_name,
IFNULL(SUM(my_inventory.have_quantity),0) AS have_quantity
FROM my_recipe
LEFT JOIN ingredient USING(raw_id)
LEFT JOIN ingredient AS ingredients USING(ingredient_name)
LEFT JOIN my_inventory ON my_inventory.raw_id = ingredients.raw_id
WHERE my_recipe.recipe_id = 853
AND my_recipe.user = 'jack'
AND my_inventory.user = 'jack'
GROUP BY ingredient_name;
Now converting into the needed structure:
$inventory = DB::table('my_recipe')
->leftJoin('ingredient', 'my_recipe.raw_id', '=', 'ingredient.raw_id')
->leftJoin('ingredient AS ingredients', 'ingredient.ingredient_name', '=', 'ingredients.ingredient_name')
->leftJoin('my_inventory', 'my_inventory.raw_id', '=', 'ingredients.raw_id')
->select(DB::raw('my_recipe.user AS user,my_recipe.raw_id AS raw_id,my_recipe.quantity AS quantity,ingredient.ingredient_name AS ingredient_name,IFNULL(SUM(my_inventory.have_quantity),0) AS have_quantity'))
->where('my_recipe.recipe_id', '=', $recipe_id)
->where('my_recipe.user', '=', $user)
->where('my_inventory.user', '=', $user)
->groupBy('ingredient_name')
->get();
Maybe this can solve you problem
//replace count by sum
$inventory = DB::table('my_inventory as tA')
->leftJoin('ingredient as tB', 'tA.raw_id', '=', 'tB.raw_id')
->leftJoin('my_recipe as tC', 'tC.raw_id', '=', 'tB.raw_id')
->select(DB::raw('tA.user as user, tB.ingredient_name as ingredient_name, SUM(tA.have_quantity) have_quantity'))
->where('user', '=', $user)
->groupBy('tB.ingredient_name, tA.user')
->get();
Let's try this:
$result = DB::table('ingredient as ing')
->rightJoin('my_recipe as rcp', 'ing.raw_id', '=', 'rcp.raw_id')
->rightJoin('my_inventory as inv', 'ing.raw_id', '=', 'inv.raw_id')
->select(DB::raw('
rcp.user as user,
ing.ingredient_name as ingredient_name,
rcp.have_quantity quantity,
SUM(inv.have_quantity) have_quantity
'))
->where('rcp.user', '=', $user)
->where('rcp.raw_id', '=', $raw_id)
->groupBy('rcp.user, ing.ingredient_name')
->get();

Laravel Eloquent query get users from another model

I have another table called tableb and it has a user relationship defined through the user_id field.
I want to run a query against tableb where a certain date is within a certain range but then I want to grab the user table associated with that row but I only want it to grab the user if it's not been grabbed yet. I'm trying to do this all in 1 DB query. I have most of it done, but I'm having trouble with the unique part of it.
Here's what I have right now:
$tableB = TableB::select('users.*')
->join('users', 'tableb.user_id', '=', 'users.id')
->where('tableb.start_date', '>', date('Y-m-d'))
->get();
So right now I have 3 entries in tableB from the same user, and ideally I'd like to only get 1 entry for that user.
How would I go about doing this?
Since you're selecting only users data, just add a groupBy clause in your query.
$tableB = TableB::select('users.*')
->join('users', 'tableb.user_id', '=', 'users.id')
->where('tableb.start_date', '>', date('Y-m-d'))
->groupBy('users.id')
->get();
You should just add groupBy like this :
$tableB = TableB::select('users.*')
->join('users', 'tableb.user_id', '=', 'users.id')
->where('tableb.start_date', '>', date('Y-m-d'))
->groupBy('users.id')
->get
Try This Code
App/user.php
public function getrelation(){
return $this->hasMany('App\tableB', 'user_id');
}
In Your Controller
Controller.php
use App/user;
public funtion filterByDate(user $user)
{
$date = '2016-02-01';
$result = $user->WhereHas('getrelation', function ($query) use($date) {
$query->whereDate('tableb.start_date', '>', $date)
->first();
});
}

How to return highest id value from a table via join with eloquent Laravel 5.2

i have two tables that share a relationship users and log table. I’m trying to query the users table and get the record from log with the highest id value
so far this is what I have that’s returning duplicate entries:
$students = User::with([
'course' => function ($query) {
$query->get(['id', 'name']);
}
])
->join('log', 'users.id', '=', 'log.user_id')
->where('log.event', 1)
->orderBy('log.id', 'desc')
->where('users.verified', 1)
->get(['users.*', 'log.id AS logid']);
Ideally, I want the last inserted record from the log table for each user
groupBy('user_id')
returns the first record
$students = User::with([
'course' => function ($query) {
$query->get(['id', 'name']);
}
])
->join('log', 'users.id', '=', 'log.user_id')
->where('log.event', 1)
->whereRaw('log.id = (select max(`id`) from log where `user_id` = users.id )')
->where('users.verified', 1)
->get(['users.*', 'log.id AS logid', 'log.user_id']);
I think you are very close to, only you need to use limit.
->where('users.verified', 1)
->take(1) // add this to get only a single record
->get(['users.*', 'log.id AS logid']);
Try the below solution with 1 more where condition without groupBy
$students = User::with([
'course' => function ($query) {
$query->get(['id', 'name']);
}
])
->join('log', 'users.id', '=', 'log.user_id')
->where('log.event', 1)
->orderBy('log.id', 'desc')
->where('users.verified', 1)
->where('log.id',DB::raw("SELECT MAX(id) FROM log WHERE log.user_id = users.id")) // get the max id value
->get(['users.*', 'log.id AS logid']);

How to determine columns that will be returned in the result when using `paginate()` method in Laravel?

I have 2 tables: users and articles. To fetch all columns from the articles table and only user_name column from the users table, I use this code:
$articles = Article::join('users', 'articles.user_id', '=', 'users.user_id')
->get(array('articles.*', 'users.user_name'));
and it works fine, but when I use paginate() method like this:
$articles = Article::join('users', 'articles.user_id', '=', 'users.user_id')
->paginate(10);
it fetches all columns from both tables, which I don't want. My question is: How can I select columns that will be returned in the result if I use paginate() method in Laravel framework?
The select function does this.
$articles = Article::join('users', 'articles.user_id', '=', users.user_id')
->select('articles.*', 'users.user_name')
->paginate(10);

Categories