Converting raw queries into laravel - php

I have this schema
product_categories
id | product_category
---------------------
1 | ABC
2 | DBC
3 | EBA
store_product_categories
id | category_id | store_id
------------------------
1 | 2 | 11
2 | 1 | 11
3 | 3 | 11
I have created a query in mysql work bench
SELECT pc.* FROM product_categories pc LEFT JOIN store_product_categories spc ON pc.category = pc.id AND spc.store_id = 11 WHERE spc.category IS NULL;
This query actually gets all those categories from product_categories table which are not present in store_product_categories.
Now I am really really confused how to build this is Laravel Eloq..
I did try this.
$exclusive_categories = Product_category::join('store_product_categories','store_product_categories.category_id','=','product_categories.id')
->where('store_product_categories.store_id','=',session('store_id'))
->where('store_product_categories.category_id','=','NULL')->get();
But this doesn't give me result

Since you're joining on two different columns, you need to pass that through a function/closure:
$exclusive_categories = Product_category::leftJoin('store_product_categories', function($join) {
$join->on('store_product_categories.category_id','=','product_categories.id')
->on('store_product_categories.store_id','=',session('store_id'));
})
->where('store_product_categories.store_id','=','NULL')->get();
I'm not sure if this is quite what you want. If you're looking for where store_id is NULL OR store_id = the session id, you can pass that through another closure/function.

$exclusive_categories = Product_category::leftJoin('store_product_categories spc', function ($join) {
$join->on('spc.category_id', '=', 'product_categories.id');
$join->on('spc.store_id', '=', \DB::raw(session('store_id')));
})
->whereNull('spc.category_id')
->get(['product_categories.*']);

$exclusive_categories = Product_category::leftJoin('store_product_categories','store_product_categories.category_id','=','product_categories.id')
->where('store_product_categories.store_id','=',session('store_id'))
->whereNull('store_product_categories.store_id')->get();
https://laravel.com/docs/5.3/queries

Related

How can we use count() with conditional sql in select() of laravel?

I have two tables as shown below. I am using Laravel DB method to join this table. But I am not getting how can I get the count of marks of students as per failed or passed. 0-failed 1-passed.
Expected result:
1. Student Name
2. Student Id,
3. Count of failed based on student Id as count_failed
4. Total Marks based on student Id as total_marks
table students
`+----+-----------+
| id | name |
+----+-----------+
| 1 | John Doe |
| 2 | Mark P |
| 3 | Pen Henry |
+----+-----------+`
table students_marks:
+----+------------+-------+-----------+
| id | student_id | marks |is_failed |
+----+------------+-------+-----------+
| 1 | 1 | 55 | 0 |
| 2 | 2 | 44 | 1 |
| 3 | 1 | 11 | 1 |
| 4 | 2 | 10 | 0 |
| 5 | 2 | 11 | 1 |
| 6 | 2 | 20 | 0 |
+----+------------+-------+-----------+
Below is query which I used:
$users = DB::table('users')
->join('contacts', 'students.id', '=', 'students_marks.user_id')
->select('student.*')
->get();
I am unable to get how can we use count() with conditional SQL in select() of laravel?
Use conditional aggregation:
$users = DB::table('students s')
->leftJoin('students_mark sm', 's.id', '=', 'sm.user_id')
->groupBy('sm.id')
->select(DB::raw('s.id, s.name, SUM(sm.is_failed) AS num_failed, COUNT(sm.user_id) AS total_cnt'))
->get();
This corresponds to the following raw MySQL query:
SELECT
s.id,
s.name,
SUM(sm.is_failed) AS num_failed,
COUNT(sm.user_id) AS total_cnt
FROM students s
LEFT JOIN students_marks sm
ON s.id = sm.user_id
GROUP BY
s.id;
Note: It is acceptable in ANSI SQL to select the name field in the above GROUP BY query assuming that student#id is the primary key column for that table. If the above query gives an ONLY_FULL_GROUP_BY error, then simply add s.name to the GROUP BY clause.
$users = DB::table('users')
->join('contacts', 'students.id', '=', 'students_marks.user_id')
->select('student.*', DB::raw("count(students_marks.is_failed) as count")))
->where('status', '=', 0)
->get();
Try this.
If this is not clear or doesn't work refer this
Try this code snippet
$table = DB::table('students_marks');
$table = $table->select(
\DB::raw('SUM(if(is_failed = '0', 1, 0)) AS failed'),
\DB::raw('SUM(if(is_failed = '1', 1, 0)) AS passed'),
\DB::raw('SUM(marks) AS total'));
$table = $table->Join('students', 'students.id', '=', 'students_marks.student_id');
$table = $table->get();
Try this
$users = DB::table('students s')
->leftJoin('students_mark sm', 's.id', '=', 'sm.student_id')
->groupBy('s.id','s.name')
->selectRaw("s.id,s.name,SUM(sm.is_failed) AS count_failed,SUM(sm.marks) as total_marks")
->get();

Select the most recent record with groupby in Laravel

I have two tables entries similar as follows:
gym_clients
+---------+---------+-----------------+
| id | first_name| last_name |
+---------+-----------+---------------+
| 1 | Name 1 | Last 1 |
| 2 | Name 2 | Last 2 |
+---------+-----------+---------------+
gym_client_purchases
+---------+---------+-----------------+
| id | client_id | purchase_date |
+---------+-----------+---------------+
| 15 | 1 | 2018-04-01 |
| 16 | 1 | 2018-05-01 |
| 17 | 2 | 2018-05-01 |
+---------+-----------+---------------+
I want to group by the purchases of each client and show the latest.
I tried this query but the groupby shows me the oldest purchase (id 15).
any ideas?
$this->data['latestSubscriptions'] = GymPurchase::select('first_name', 'last_name', 'gym_client_purchases.*')
->leftJoin('gym_clients', 'gym_clients.id', '=', 'client_id')
->groupBy('gym_client_purchases.client_id')
->orderBy('gym_client_purchases.purchase_date', 'desc')
->get();
Thanks in advance.
If you are explicitly calling the table names to specify their columns, isn't that supposed to be the same on the ON clause? on your code it's like this
$this->data['latestSubscriptions'] = GymPurchase::select('first_name', 'last_name', 'gym_client_purchases.*')
//client_id here isn't specified
->leftJoin('gym_clients', 'gym_clients.id', '=', 'client_id')
->groupBy('gym_client_purchases.client_id')
->orderBy('gym_client_purchases.purchase_date', 'desc')
->get();
It should be like this:
$this->data['latestSubscriptions'] = GymPurchase::select('first_name', 'last_name', 'gym_client_purchases.*')
->leftJoin('gym_clients', 'gym_clients.id', '=', 'gym_client_purchases.client_id')
->groupBy('gym_client_purchases.client_id')
->orderBy('gym_client_purchases.purchase_date', 'desc')
->get();
I tested your code, it should be working properly due to the orderby descending, I think just a little typo on your code snippets
First, when you use group by you have o specify in this clause the columns for which the query is gioing to group, so I suggest to you to try you query on sql engine.
You will have something like this
select first_name, last_name, A.*
from gym_client_purchases A
left Join gym_clients B on B.id = A.client_id
group by A.client_id
order By A.purchase_date desc
and you will notice that it doesn't work
Maybe what you want is something like this
select A.client_id, B.first_name, B.last_name, max(A.purchase_date)
from gym_client_purchases A
left Join gym_clients B on B.id = A.client_id
group by A.client_id, B.first_name, B.last_name
order By max(A.purchase_date) desc

MySQL Join Table in Codeigniter

I'm new in PHP and CodeIgniter. I have a problem.
Here is what my database looks like:
Table 1 :
---------------------------------------------
| id_table1 | data_table1_1 | data_table1_2 |
---------------------------------------------
Table 2 :
---------------------------------------------------------
| id_table2 | id_table1 | data_table2_1 | data_table2_2 |
---------------------------------------------------------
Table 3 :
---------------------------------------------------------
| id_table3 | id_table2 | data_table3_1 | data_table3_2 |
---------------------------------------------------------
I'm selecting my table data from Table 3, and i join with Table 2. My question is, how can i get the data from Table 1 with other ways or join to get data_table1_1 without adding id_table1 in Table 3 ? Thankyou :)
hope this will work for you
$sql = "SELECT * from table 3
JOIN table 2 ON table 2.id = table 3.id
JOIN table 1 on table 1.id = table 2.id
";
$res = $this->db->query($sql);
Without data information gets difficult.
You can do it:
$this->db->select()
->from('table3')
->join('table2', 'table3.id_table2 = table2.id_table2', 'INNER')
->join('table1', 'table2.id_table1 = table1.id_table1', 'INNER')
->get()
->result_array();

Codeigniter. How to get sum of database columns

I have two tables .
pre_order
receive_pre_order
My Question is how to get all the information from pre_order table and get the SUM of all the quantity received form receive_pre_order table against that pre_order id.
To make it clear suppose we have the following data in recieve_pre_order .
+--------------+------------+-------------------+
| pre_order_id | product_id | quantity_recieved |
+--------------+------------+-------------------+
| 1 | 1 | 10 |
| 1 | 1 | 20 |
| 1 | 1 | 10 |
+--------------+------------+-------------------+
It should return quantity_recieved = 40 against pre_order_id 1 .
Right now I have tried:
$this->db->select_sum('quantity_recieved');
$this->db->from('recieve_pre_order');
return $this->db->get();
It is working but, it is getting data from one table.
But I want to fetch data from both tables.
Join the two tables tables (rpo.pre_order_id = po.id). Group the result for po.id, so all Rows with the same po.id will be grouped into one row. sum(rpo.quantity_recieved) will sum up the quantity for these groups.
select po.id, sum(rpo.quantity_recieved)
from receive_pre_order rpo
join pre_order po on rpo.pre_order_id = po.id
group by po.id;
try this
$this->db->select("sum(recieve_pre_order.quantity_recieved),pre_order.id");
$this->db->from('recieve_pre_order');
$this->db->join("pre_order",'recieve_pre_order.pre_order_id = pre_order.id','left outer');
$this->db->where('recieve_pre_order.pre_order_id',your parameter);
$this->db->select('pre_order.*');
$this->db->select_sum('recieve_pre_order.quantity_recieved');
$this->db->from('pre_order');
$this->db->join("recieve_pre_order",'recieve_pre_order.pre_order_id = pre_order.id','left');
try sub query instead of joining table.
$this->db->select("po.*,SELECT(SUM(quantity_recieved) from receive_pre_order where pre_order_id = po.id) as total_recieved_quantity",FALSE);
$this->db->from('pre_order as po');
return $this->db->get();

mysql query 3 tables php output name instead id

Need some help.
I have got 3 tables. klients, klientwithservice, service.
table klients
id | klientrnd
---------
1 | 11231231
2 | 22222222
table service
id | servicename
---------
1 | Repair laptop
2 | Repair pc
table klientwithservice
id | klientrnd | serviceid
-------------------------------
1 | 11231231 | 1
2 | 11231231 | 2
3 | 22222222 | 1
4 | 22222222 | 2
I need to output SERVICENAME instead ID.
My sql query is:
SELECT serviceid FROM klientwithservice WHERE '$pole8' = `klientrnd`
Where $pole8 = klientrnd exactly person on which page i placed.
for this you need to JOIN two table
use below query
SELECT s.servicename FROM klientwithservice as kws
JOIN service as s ON s.id = kws.serviceid
WHERE `klientrnd` = '$pole8'
Firstly your sql SELECT serviceid FROM klientwithservice WHERE '$pole8' = klientrnd is wrong.
It will return a syntax error stating the unknown column $pole8 (it's exact value) `is wrong
Second you should use join to achieve what you're after. Try this:
SELECT s.servicename FROM klientwithservice as k
JOIN service as s ON s.id = k.serviceid
WHERE k.klientrnd = '$pole8'

Categories