how to pass a pure sql query to laravel eloquent - php

This SQL:
SELECT COUNT(*) AS total_see_all_video
from users u
WHERE 7 = (SELECT COUNT(*) FROM lecciones_users lu WHERE lu.uuid = u.uuid)
I tried this code but did not work:
$data = LeccionesUsers::select(
DB::raw('COUNT(*) AS total_ase_vis_videos'),
DB::raw('where 7 = (SELECT COUNT(*) FROM lecciones_users where leccion_users.uuid = users.uuid)')
)
->join('users', 'lecciones_users.uuid', '=', 'users.uuid')
->get();

Your issue is that you are not correctly forming your query. You can do ->toSql(); instead of ->get(); and you would see the final SQL (would definitely not be the same as the one you wrote first).
So, you should have this to have the same SQL:
$total_see_all_video = LeccionesUsers::whereRaw('7 = (SELECT COUNT(*) FROM lecciones_users where leccion_users.uuid = users.uuid)')
->count();
Please, try my query (and also run ->toSql() to see if you have a correct SQL).
I would still recommend to use relationships and it is very weird to do 7 = query.

You can use
DB::query()->fromSub('Raw sql query here..')
and then can perform actions on this.For the reference you can use the documentation fromSub
You can also look into this convert this where break this query to parts to be used accordingly. You can use this section for the reference purpose:
Laravel-Raw-Expressions
Hope this will help you with the result.

Related

How to convert raw SQL query to Laravel Query Builder

I need a following code to convert to Laravel query can any one help me with these.
SELECT id, `leave_name`, `total_leave_days`, leave_id, leave_taken_days FROM `leaves` AS t1 INNER JOIN ( SELECT leave_id, SUM(`leave_taken_days`) AS leave_taken_days FROM `leave_applications` WHERE user_id = 2 AND statuses_id = 2 GROUP BY leave_id ) AS t2 ON t1.id = t2.leave_id
I even tried but the output is not showing atall.
$user_leaves = DB::table('leaves')
->select('id', 'leave_name', 'total_leave_days', 'leave_id', 'leave_taken_days')
->join('leave_application', 'leave_application.leave_id', '=', 'leave.id')
->select('leave_application.leave_id', DB::raw("SUM(leave_taken_days) as leave_application.leave_taken_days"))
->where('user_id','=', 2)
->where('statuses_id','=', 2)
->get();
How can I solve this issue?
UPDATE
Relations between two models.
Leave Model
public function leave_application()
{
return $this->belongsTo(LeaveApplication::class, 'id' , 'leave_id');
}
Leave Application Model
public function leave()
{
return $this->belongsTo(Leave::class, 'leave_id', 'id');
}
Try this :
$user_leaves = Leave::select('leaves.id', 'leaves.leave_name', 'leaves.total_leave_days', 'leave_applications.leave_id', DB::raw('SUM(leave_applications.leave_taken_days) as leave_taken_days'))
->with('leave_application')
->whereHas('leave_application', function($q) {
$q->where('user_id', 2)
->where('statuses_id', 2);
})
->groupBy('leaves.id')
->get();
On this topic I would like to give my recommendations for some tools to help you out in the future.
SQL Statement to Laravel Eloquent to convert SQL to Laravel query builder. This does a decent job at low level queries. It also saves time when converting old code.
The other tool I use to view the query that is being run is Clock Work
I keep this open in a tab and monitor slow nasty queries or, also gives me perspective on how the query builder is writing SQL. If you have not use this extension I highly recommend getting and using it.
Actually I found my answer,
$user_leaves = DB::table('leaves as t1')
->select('t1.id', 't1.leave_name', 't1.total_leave_days', 't2.leave_id', 't2.leave_taken_days')
->join(DB::raw('(SELECT leave_id, SUM(leave_taken_days) AS leave_taken_days FROM leave_applications WHERE user_id = ' . $user_id . ' AND statuses_id = 2 GROUP BY leave_id) AS t2'), function ($join) {
$join->on('t1.id', '=', 't2.leave_id');
})
->get();
You can use DB:select("your query", params) and put your query and params (as an array (optional)
As below sample:
$result = DB:select("
SELECT id, `leave_name`, `total_leave_days`, leave_id, leave_taken_days
FROM `leaves` AS t1
INNER JOIN (
SELECT leave_id, SUM(`leave_taken_days`) AS leave_taken_days
FROM `leave_applications`
WHERE user_id = 2
AND statuses_id = 2
GROUP BY leave_id
) AS t2 ON t1.id = t2.leave_id" , $params
);
return response()->json($result);

Laravel Query Builder returns no results while generated SQL works perfect

I am actively working on a laravel project and have ran into some issues with the Query Builder. I am trying to avoid using DB::Raw but it is looking like I may need to.
$query = app($this->model());
$query = $query->select(['last_name', 'first_name', 'birthday'])
->distinct()
->leftJoin('enrollments', 'students_meta.uid', '=', 'enrollments.student_uid')
->whereIn('enrollments.type', $types)
->where('enrollments.startdate', '<=', "'{$today}'")
->where(function ($join) use ($today) {
$join->where('enrollments.dropdate', '>=', "'{$today}'")
->orWhereNull('enrollments.dropdate');
});
// todo: add viewBy filter
$query = $query->where('birth_month', '=', Carbon::today()->month);
$query = $query->orderBy('last_name')->orderBy('first_name');
$models = $query->get();
The above query builder generates the following SQL :
SELECT distinct `last_name`, `first_name`, `birthday`
FROM `students_meta`
LEFT JOIN `enrollments` ON `students_meta`.`uid` = `enrollments`.`student_uid`
WHERE `enrollments`.`type` IN ('ACTIVE', 'active')
AND `enrollments`.`startdate` <= '2019-10-29'
AND (`enrollments`.`dropdate` >= '2019-10-29' OR `enrollments`.`dropdate` IS NULL)
AND `birth_month` = 10
ORDER BY `last_name` asc, `first_name` asc;
The generated SQL is perfect based on the old code I'm moving from and produces the expected results. If I move some things around, it seems I can get the query builder to return results, but they're not the correct ones. I've looked at other questions/answers about this kind of problem and tried multiple scenarios of moving the join/changing the where's around, still no luck.
Any suggestions? (other than taking the generated sql and running it in DB::Raw()
$query = $query->orderBy('last_name')->orderBy('first_name')->get();
Your query worked fine but you didn't output it.
You can also use ->get()->toArray(); to retrieve the data in array format
Remove your quotes from around $today. The third (or second, if you eliminate the comparison operator) parameter of the where clause sends the values as a parameter in a prepared statement . So
"'{$today}'"
would look like this in a straight query:
where enrollments.startdate <= "'2019-10-29'"
So change your query to
->where('enrollments.startdate', '<=', $today)
Make sure you remove the quotes from all instances like this in your query.

Create SQL Query in Laravel 4.2

I am new to Laravel but I would like to create this Query(MySQL):
SELECT
*
FROM
(
SELECT
ce.empresa_id,
CONCAT(ce.nombre, ' ', ce.apellido) AS nombre,
ce.grupo_contable
FROM
cliente_empresa AS ce
UNION
SELECT
cc.empresa_id,
cc.nombre,
cc.grupo_contable
FROM
cuenta_contable AS cc
UNION
SELECT
cci.empresa_id,
cci.grupo_iva AS nombre,
cci.cuenta_contable AS grupo_contable
FROM
cuenta_contables_iva AS cci
) AS cuentasContables
WHERE
cuentasContables.empresa_id = 1
AND (cuentasContables.nombre LIKE '%a%'
OR cuentasContables.grupo_contable LIKE '%%')
Looking at Documentation I can't find the proper way to do it. Thank you.
Normally, for a query that the ORM can't manage, you would probably want to simply call \DB::raw:
$results = \DB::table('users')
->select(\DB::raw(/* your stuff here */))
However in your case, you might want to consider sticking to the ORM. It looks like you might want to try something like:
$first = DB::table('cliente_empresa')
->where('empresa_id', '=', 1);
$second = DB::table('cuenta_contable')
->where('empresa_id', '=', 1);
$results = DB::table('cuenta_contables_iva')
->where('empresa_id', '=', 1)
->union($first)
->union($second)
->get();
Obviously, you'll need to put your SELECT column statements in there as well.

Laravel SQL Query difficult

I can't "translate" the SQL Query below to Laravel, how I can make this?
SELECT SUM(transactions.amount) AS total, products.name
FROM transactions, product_stock, product_catalog, products
WHERE transactions.id_product_stock = product_stock.id_prodct_stock
AND product_stock.id_product_catalog = product_catalog.id_product_catalog
AND product_catalog.id_product = products.id_produto
GROUP BY (products.name);
I tried this (returns error):
Transaction::join('product_stock', 'transactions.id_product_stock', '=', 'product.stock.id_product_stock')
->join('product_catalog', 'product_stock.id_product_catalog', '=', 'product_catalog.id_product_catalog')
->join('products', 'product_catalog.id_product', '=', 'products.id_product')
->groupBy('products.name')
->get([ DB::raw('SUM(transactions.amount) AS total'), DB::raw('products.name as name')]);
And this (returns empty):
DB::raw('select SUM(transactions.amount) AS total, products.name
from transactions, product_stock, product_catalog, products
where transactions.id_product_stock = product_stock.id_prodct_stock
and product_stock.id_product_catalog = product_catalog.id_product_catalog
and product_catalog.id_product = products.id_produto
group by (products.name)');
Anyone can help me?
If you want to run the raw query (and for a complex query like this, I would stick with the raw SQL because I'm more comfortable with that), what you need to do is this:
$value = DB::select('select SUM(transactions.amount) AS total, products.name
from transactions, product_stock, product_catalog, products
where transactions.id_product_stock = product_stock.id_prodct_stock
and product_stock.id_product_catalog = product_catalog.id_product_catalog
and product_catalog.id_product = products.id_produto
group by (products.name)'
);
Here's the documentation for use of the DB::select() method.
DB::raw() is used to mark part of a larger query expression as raw SQL. See http://laravel.com/docs/queries#raw-expressions for details & examples.
quick checking their documentation it looks like you want to run your entire query as a raw expression.
http://laravel.com/docs/queries#raw-expressions
hth

Joining with OR in Kohana

I'm trying to combine two tables based on if they match a given pair in a many-to-many relation. I already know the SQL statement I'm trying to produce, which is functionally equivalent to the following:
SELECT columnA, columnB, ...
...
JOIN matching_table
ON ( (matching_table.id1 = table_a.id AND matching_table.id2 = table_b.id) OR
(matching_table.id1 = table_b.id AND matching_table.id2 = table_a.id) )
...
But I want to produce it using Kohana's query builder for consistency. The problem is I can't seem to find a way of creating a complex ON query. So far all I've got is
DB::select('columnA', 'columnB', ...)
...
->join('matching_table')
->on('matching_table.id1', '=', 'table_a.id')
->on('matching_table.id2', '=', 'table_b.id')
...
and this generates the first AND sequence but I can't seem to put it together with an OR.
Any suggestions?
You should be able to use where instead of on (not tested though):
->join('matching_table')
->where_open()
->where('matching_table.id1', '=', 'table_a.id')
->and_where('matching_table.id2', '=', 'table_b.id')
->where_close()
->or_where_open()
->where('matching_table.id1', '=', 'table_b.id')
->and_where('matching_table.id2', '=', 'table_a.id')
->or_where_close()

Categories