Only show items that are not in other table laravel - php

I would like to only show the schools that are not favorited.
to get the ones favorited I use:
$favorite_schools = DB::table('favorite_schools')
->select('favorite_schools.*', 'schools.name')
->leftJoin('schools', 'schools.id', 'favorite_schools.school_id')
->get();
Schools table:
Schema::create('schools', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('active');
$table->timestamps();
});
Favorite_schools table:
Schema::create('favorite_schools', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->integer('school_id');
$table->timestamps();
});
How can I only get the schools that have not been favorited yet?

You need to go the other way. Get the schools, and left join on the favorites table, then get the results that does not have a result in the favorite_schools table.
$favorite_schools = DB::table('schools')
->select('schools.name', 'schools.id')
->leftJoin('favorite_schools', 'schools.id', 'favorite_schools.school_id')
->whereNull('favorite_schools.school_id')
->get();

Add WhereNull('favorite_schools.school_id') to the query you use to get the favorite ones. that will give you the not favorite schools.
Good luck

a slightly different approach would be to use whereNotExists
usage would be something like this:
$schools = DB::table('schools')
->whereNotExists(function ($query) {
$query->select(DB::raw(1))
->from('favorite_schools')
->whereRaw('favorite_schools.school_id = school.id');
})
->get();

Related

Change Primary ID in laravel Migration

I'm creating a table where I want to use the ID from this table "menu_items" to be added in another table
Table one: menu_items
Schema::create('menu_items', function (Blueprint $table) {
$table->id('menu_level_item_id');
$table->timestamps();
$table->string('menu_item_name');
$table->string('menu_item_desc');
Table 2 products
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('product_name');
$table->string('product_desc');
$table->integer('price');
$table->integer('menu_level_item_id');
$table->timestamps();
});
My aim of doing this is that I can then create a relationship between the 2 tables as they have the same key?
Is there a different approach I can take? Should I create a unique key when creating a menu item and then add this to the second table?
Thank you.
Basically Laravel Eloquent do the key handling. When you have two tables which both has as key the name id, this is not a problem. Name the keys in the relation table just like this
table1_id
table2_id
Laravel will handle this in Eloquent. You are also able to name the two columns in the relation table to what ever you want. You could define it for the relation in Eloquent. E.g.
public function otherModel () {
return $this->belongsToMany('App\Models\OtherModel', 'table_name', 'this_model_id', 'other_model_id');
}
Please have a look into:
Laravel Relationship Documentation
Schema::create('menu_items', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('menu_item_name');
$table->string('menu_item_desc');
table->timestamp();
});
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('product_name');
$table->string('product_desc');
$table->integer('price');
$table->unsignedBigInteger('menu_level_item_id');
$table->timestamps();
$table->foreign('menu_level_item_id')->references('id')->on('menu_items');
});

Select statement with group_concat not working when other columns are called in laravel

Hello my laravel code is
$productDetails = DB::table('products')
->select(DB::raw('products.name, GROUP_CONCAT(sizes.name) as sizesName'))
->join('subcategories', 'products.subcategories_id', '=', 'subcategories.id')
->join('size_categories', 'subcategories.categories_id', '=', 'size_categories.categories_id')
->join('sizes',function($join){
$join->on(DB::raw("FIND_IN_SET(sizes.id, size_categories.size_id)"),">",DB::raw("'0'"));
})
->where('products.id', $request->id)
->get();
This doesnt work, when i useproducts.name or any other column name in select statement
but when i use only group_concat inside Db::raw and nothing else, the query works.
So how do i fetch other columns?
Please help.
I am stuck on it for quite a while
The query i want is
select GROUP_CONCAT(sizes.name),`products`.`name`, `products`.`image`, `products`.`id`, `products`.`image_second`, `products`.`description`, `products`.`min_order`, `size_categories`.`size_id` from `products`
inner join `subcategories` on `products`.`subcategories_id` = `subcategories`.`id`
inner join `size_categories` on `subcategories`.`categories_id` = `size_categories`.`categories_id`
join sizes on (FIND_IN_SET(sizes.id,size_categories.size_id)>0) where `products`.`id` = '7'
Please note that the above query is working fine. I just cant make it in laravel to work. Only the group_concat part.
This is the screenshot from my database, when i dont use group_concat
Also the DISTINCT part is doing nothing there, please ignore it.
I was just trying that out
This is the migration of create_products_table
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('units_id');
$table->unsignedBigInteger('selections_id');
$table->unsignedBigInteger('subcategories_id');
$table->string('name');
$table->string('image');
$table->text('description');
$table->string('min_order');
$table->timestamps();
$table->index('units_id');
$table->index('selections_id');
$table->index('subcategories_id');
});
}
migration of create_subcategories_table
public function up()
{
Schema::create('subcategories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->unsignedBigInteger('categories_id');
$table->timestamps();
$table->index('categories_id');
});
}
data of size_categories table
public function up()
{
Schema::create('size_categories', function (Blueprint $table) {
$table->id();
$table->string('size_id');
$table->unsignedBigInteger('categories_id');
$table->timestamps();
$table->index('categories_id');
});
}
migration of categories table
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
migration of sizes table
public function up()
{
Schema::create('sizes', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
In sizes table data is in this form
id name
1 2m
2 3m
3 4m
First, you need to specify select columns separately. Like so:
->select(DB::raw('products.name'), DB::raw('GROUP_CONCAT(sizes.name) as sizesName'))
Next, since group concat is an aggregate column, you need to group the sizes, and product name since it's in the select list and it is not related to size.
->groupBy('size_categories.size_id', 'products.id') //edit after your comment. group by prodcuts.id to be able to select columns from products table.
So your final query should look like this:
$productDetails = DB::table('products')
->select(DB::raw('products.name'), DB::raw('GROUP_CONCAT(sizes.name) as sizesName'))
->join('subcategories', 'products.subcategories_id', '=', 'subcategories.id')
->join('size_categories', 'subcategories.categories_id', '=', 'size_categories.categories_id')
->join('sizes',function($join){
$join->on(DB::raw("FIND_IN_SET(sizes.id, size_categories.size_id)"),">",DB::raw("'0'"));
})
->where('products.id', 7)
->groupBy('size_categories.size_id', 'products.id')
->get();

Laravel - Eloquent - How to sum related data and query agaist it?

I'm looking for help with database queries, not collection solution
I have the following models:
User
Order
Product
User hasMany orders, and orders belongsToMany products
I'm in a place where I would need to query users and select all sold products, meaning the sum of all products quantities that are attached to the orders.
quantity value is stored in the order_product pivot table.
Table name: users, orders, products & order_product
Ideally, I would like to make queries like: select all users that have sold at least 100 products, for example.
DB::raw() & selectRaw is most likely the way to go, I think(?), but I'm not sure about the syntax and how to actually make the query, with and without where clause.
Thanks a lot in advance, this has bothered me for a while
Database Schemas
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
});
Schema::create('orders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id')->index();
});
Schema::create('order_product', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('order_id')->index();
$table->unsignedBigInteger('product_id')->index();
$table->integer('quantity')->unsigned()->default(1);
});
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
});
UPDATE
This far I have come:
\App\User::addSelect([
'sold_products_count' => \App\Order::whereColumn('user_id', 'users.id')
->join('order_product', 'orders.id', '=', 'order_product.order_id')
->select(DB::raw('sum(order_product.quantity) as qty')),
])->where('users.sold_products_count', '>=', 100);
HOWEVER, the last statement where('users.sold_products_count', '>=', 100) throws error, cuz there's no sold_products_count column.
So I think I'm on the right track, but how I can use the new sum column in where clause?
Can I use addSelect, or do I have to use something else?
Finally, I solved this
Here's the answer:
\App\User::addSelect([
'sold_products_count' => \App\Order::whereColumn('user_id', 'users.id')
->join('order_product', 'orders.id', '=', 'order_product.order_id')
->select(DB::raw('sum(order_product.quantity) as qty')),
])->having('sold_products_count', '>=', 100);
The idea is to first count the sum via addSelect and then we can query against the value using having, neat
DB::table('users')
->join('orders', 'orders.user_id', '=', 'users.id')
->join('order_product', 'orders.id', '=', 'order_product.order_id')
->select('users.*', DB::raw('sum(order_product.quantity) as qty'))
->having('qty', '>=', 100)
->get();

Laravel multiple tables data filter

I am using Laravel 5 and I have 3 database tables projects, applications, users and their table structure are as followed:
Projects
Schema::create('projects', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->text('description');
$table->char('status',1);
$table->timestamps();
});
Applications
Schema::create('applications', function (Blueprint $table) {
$table->increments('id');
$table->integer('project_id')->unsigned()->index();
$table->integer('user_id')->unsigned()->index();
$table->char('status');
$table->timestamps();
});
Users
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('role');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
Now, I wanted to perform a query to return all the projects where a specific user has not submitted any application to that project yet. So far this is the closest result I could get but it will return NULL in the projects.id for every projects that have no applications.
DB::table('projects')
->leftjoin('applications', 'applications.project_id', '=', 'projects.id')
->where('applications.user_id', '!=', $user->id)
->orWhereNull('applications.id')
->get();
Query Result
{
"total":1,
"per_page":5,
"current_page":1,
"last_page":1,
"next_page_url":null,
"prev_page_url":null,
"from":1,"to":1,
"data":[{
"id":null,
"name":"Project2",
"description":"Project2 detail",
"status":null,
"created_at":null,
"updated_at":null,
"project_id":null,
"user_id":null
}]
}
Does anyone has a solution to this?
DB::table('projects')
->leftjoin('applications', function($join){
$join->on('applications.project_id', '=', 'projects.id')
->where('applications.user_id', '=', $user->id);
})
->whereNull('applications.id')
->get();
Think that's what your looking for
I just figure out how to do this by using two different query and combined them together.
1) Select all user applications' project_id
$user_applications = Application::where('user_id', '=', $user->id)
->select('project_id as id')
->get();
2) Select the projects where the projects are not from previous list
$projects_not_applied = DB::table('projects')
->whereNotIn('id',$user_applications)
->get();
Query result (user has not apply for project 2):
[{
"id":"2",
"name":"Project2",
"description":"Project2 detail",
"status":"n",
"created_at":"2016-03-14 15:09:58",
"updated_at":"2016-03-14 15:09:58"
}]

represent my sql query in laravel Eloquent

I have an application tha i want it to make bookings but i'am having trouble making my Eloquent query
I have two modals "Booking.php" and "Room.php" my bookings migrations table is as follows
Schema::create('bookings', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->integer('phone');
$table->integer('time_in');
$table->integer('room_id');
$table->integer('time_out');
$table->string('days');
$table->string('type');
$table->integer('expiry_status'); /*expiry status 0->expired 1->not expired*/
$table->timestamps();
});
and my rooms migrations table is as follows
Schema::create('rooms', function(Blueprint $table)
{
$table->increments('id');
$table->integer('room_no');
$table->integer('price');
$table->timestamps();
});
in my view i have got inputs for satrt of reservation(time_in) and end of reservation(time_out) now if there is a reservation that does not end before or start after the reservation we want, the room is considered busy therefore i do not want to show that room show those rooms for my reservation dates.
My problem is I want to know the rooms available between my reservation dates,Can someone help me to write the eloquent to get the available rooms from the above table structures. I'm using mysql as the database engine. Thanks in advance.
I found this query to be useful but how to i implement it in the form of Eloquent model
SELECT r.id
FROM rooms r
WHERE r.room_id NOT IN (
SELECT b.room_id FROM bookings b
WHERE NOT (b.time_out < '2012-09-14T18:00'
OR
b.time_in > '2012-09-21T09:00'))
ORDER BY r.room_id;
You can create subselects and advanced where conditions in Laravel Eloquent.
This script worked for me. I tried to build it for your schema.
DB::table('rooms')
->whereNotIn('room_id', function($query)
{
$query->select('room_id')
->from(with(new Booking)->getTable())
->where(function($query)
{
$query->where('time_out', '<', '2012-09-14T18:00')
->orWhere('time_in', '>', '2012-09-21T09:00');
});
})
->orderBy('room_id')
->get();
https://gist.github.com/DengoPHP/d3e95441a7b9e27299b7

Categories