Laravel select db raw groupBy - php

I would like to display this query in laravel :
SELECT products.*, (
SELECT COUNT(*)
FROM category
WHERE category.product_id = products.id
AND category.date_creation BETWEEN '2018-02-16 00:00:00' AND '2018-02-19 23:59:59'
GROUP BY product_id
)nbr
FROM products
i try with this :
$a= $date_du;
$b = $date_au;
$products = DB::table('products')
->leftjoin('category','category.product_id','=','products.id')
->select('products.*',
DB::raw("(SELECT COUNT(*) FROM category
WHERE category.product_id = products.id AND category.date_creation >= '$a' AND category.date_creation <= '$b' group by product_id) as nbr"))
->get();
But clause group by doesn't work.

Try this one,
$products = DB::table('products')
->leftjoin('category','category.product_id','=','products.id')
->whereBetween('date_creation',[$a,$b])
->select(DB::raw('COUNT(*) as nbr'), 'products.*')
->groupBy('id')
->get();
This might work for you.

You can also do this :
$products=DB::select("SELECT products.*, ( SELECT COUNT(*) FROM category WHERE category.product_id = products.id AND category.date_creation BETWEEN '2018-02-16 00:00:00' AND '2018-02-19 23:59:59' GROUP BY product_id )nbr FROM products" );
This will run a raw query and will return the desired output.

Related

How to add group by to eloquent query after unionAll in Laravel?

I want to convert this Mysql code to Laravel Eloquent
select service_id, sum(cnt) from
(
select * from
(
select service_id, count(*) cnt from prdouct_notifs
join products on products.id = prdouct_notifs.product_id
where prdouct_notifs.user_id = 268
and prdouct_notifs.deleted_at is null
and prdouct_notifs.block = 4
group by service_id
) first_table
union All
(
select service_id, count(*) cnt from products
where products.pro_user_id = 268
and products.status = 47575
group by service_id
)
) total_union group by service_id
I changed this code to Laravel Eloquent.
$get_product = Product::where('pro_user_id', 268)
->where('status', 47575)
->groupby('service_id')
->selectRaw('service_id ,count(*) cnt');
$get_final_product = prdouct_notifs::join('products', function ($join){
$join->on('products.id', '=', 'prdouct_notifs.product_id')
->where('prdouct_notifs.user_id', 268)
->where('prdouct_notifs.block', 4);
})
->selectRaw('service_id ,count(*) cnt')
->groupby('service_id')
->unionAll($get_product)
->get();
the question is how to run groupby after unionAll
That's what I want to changed into eloquent.
total_union group by service_id
My idea is to put the UNION into a sub query before grouping. I hope this answers to your question.
$product = DB::table('products as p')
->where('p.status', 47575)
->select('p.service_id as service_id');
$productNotify= DB::table('prdouct_notifs as pn')
->select('pn.service_id as service_id')
->union($product);
$groupby = DB::query()->fromSub($productNotify, 'p_pn')
->select('service_id', DB::raw('COUNT(*) as cnt'))
->groupBy('service_id');
Which produce the following SQL
select "stud_id", COUNT(*) as total_asset from (
select * from (select p.service_id as service_id from products as p)
union
select * from (select pn.service_id as service_id from prdouct_notifs as pn)
) as p_pn
group by service_id

Convert sql inner join to laravel eloquent ORM

I'm having difficulty converting a SQL to the eloquent of laravel, specifically in the part of an inner join, where I make the comparison in a "in" different of the "="
Query:
SELECT
titulo_id as titulo_id,
-- calculate both SUMs, select values for each dependent by what value it matches to
SUM(CASE WHEN ativos_extratos.data_import_id = borders.min_id THEN valor_bruto_atual END) AS valor_min,
SUM(CASE WHEN ativos_extratos.data_import_id = borders.max_id THEN valor_bruto_atual END) AS valor_max,
data_imports.data_import AS created_at,
week(data_imports.data_import) AS weeknumber
FROM
ativos_extratos
INNER JOIN
titulos ON titulo_id = titulos.id
INNER JOIN
representantes ON representante_id = representantes.id
INNER JOIN
data_imports ON data_import_id = data_imports.id
INNER JOIN ( SELECT
MIN(ID) as min_id,
MAX(ID) as max_id
FROM
data_imports
WHERE
data_import BETWEEN '2018-11-01' AND '2018-12-10'
GROUP BY week(data_import)
) borders ON ativos_extratos.data_import_id IN (borders.min_id, borders.max_id)
WHERE
user_id = 1
AND data_imports.data_import BETWEEN '2018-11-01' AND '2018-12-10'
GROUP BY titulos.nome_titulo , weeknumber
Current Eloquent ORM
$rows = AtivosExtrato::select('titulo_id',
DB::raw('SUM(CASE WHEN ativos_extratos.data_import_id = borders.min_id THEN valor_bruto_atual END) AS valor_init'),
DB::raw('SUM(CASE WHEN ativos_extratos.data_import_id = borders.max_id THEN valor_bruto_atual END) AS valor_end'),
'data_imports.data_import AS created_at',
DB::raw('month(data_imports.data_import) AS weeknumber')
)
->join('titulos','titulo_id', '=', 'titulos.id' )
->join('representantes','representante_id', '=', 'representantes.id' )
->join('data_imports','data_import_id', '=', 'data_imports.id' )
->join(DB::raw("
( SELECT
MIN(ID) as min_id,
MAX(ID) as max_id
FROM
data_imports
WHERE
data_import BETWEEN '2018-10-01' AND '2018-12-10'
GROUP BY month(data_import)) borders
"), function ($join){
$join->on('ativos_extratos.data_import_id', 'in', "(borders.min_id, borders.max_id')");
})
->where('user_id', Auth::user()->id)
->whereBetween('data_import', ['2018-01-01', '2018-12-10'])
->groupBy('titulos.nome_titulo')
->groupBy('weeknumber')
->orderBy('data_import')
->orderBy('titulos.nome_titulo')
->get();
The problem is at the time I do the join using the "in", but it does not run as it should, it concatenates "=" and other fields.
You can try to use whereIn,
Here is an example :
$users = DB::table('users')
->whereIn('id', array(1, 2, 3))->get();
Try something like :
$join->whereIn('ativos_extratos.data_import_id', '(borders.min_id, borders.max_id)');
instead of $join->on('ativos_extratos.data_import_id', 'in', "(borders.min_id, borders.max_id')");
More documentation: https://laravel.com/docs/5.0/queries and
https://github.com/illuminate/database/blob/master/Query/Builder.php#L824

Subqueries in Laravel/Eloquent not working

I am currently working on a Lumen based application and I am stuck on an Eloquent/Laravel query. What I am currently working on is this:
$min = $filter['min_spending']*100;
$query = User::isCustomer()
->with("interests")
->leftJoin("points_history", "points_history.user_id", "=", "users.id")
->leftJoin("collections", "collections.user_id", "=", "users.id")
->select("users.*",
DB::raw("(SELECT SUM(amount) FROM points_history
WHERE points_history.user_id = users.id
AND points_history.confirmed = true ) as total_points"),
DB::raw("(SELECT SUM(price) FROM collections
WHERE paid_at IS NOT NULL
AND refunded_at IS NULL
AND collections.user_id = users.id) as total_purchase"),
DB::raw("(SELECT SUM(collections.price)) as current_purchase"))
->where("total_purchase", ">=", $min);
// other relevant code here
$query->groupBy('users.id')->orderBy('users.created_at', 'desc');
However, when I try to get the result, I get this error:
{"error":"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'total_purchase >=' in 'where clause' (SQL: select count(*) as aggregate from `users` left join `points_history` on `points_history`.`user_id` = `users`.`id` left join `collections` on `collections`.`user_id` = `users`.`id` where `users`.`deleted_at` is null and `role` = 2 and `total_purchase >=` = 200000 group by `users`.`id`)"}
The subqueries did not seem to register which is causing the problem (?) My desired SQL Statement is this:
SELECT users . *,
(SELECT
SUM(amount)
FROM
points_history
WHERE
points_history.user_id = users.id
AND points_history.confirmed = true) AS total_points, (SELECT
SUM(price)
FROM
collections
WHERE
paid_at IS NOT NULL
AND refunded_at IS NULL
AND collections.user_id = users.id) AS total_purchase, SUM(collections.price) AS current_purchase
from
users
left join
points_history ON points_history.user_id = users.id
left join
collections ON collections.user_id = users.id
where
users.deleted_at is null AND (SELECT
SUM(price)
FROM
collections
WHERE
paid_at IS NOT NULL
AND refunded_at IS NULL
AND collections.user_id = users.id) >= 200000
GROUP BY users.id
where 200000 is $min. Could anyone help me pinpoint what the problem is in my query so I can figure out how to fix it?
You should try this:
$min = $filter['min_spending']*100;
$query = User::isCustomer()
->with("interests")
->leftJoin("points_history", "points_history.user_id", "=", "users.id")
->leftJoin("collections", "collections.user_id", "=", "users.id")
->select("users.*",
DB::raw("(SELECT SUM(amount) FROM points_history
WHERE points_history.user_id = users.id
AND points_history.confirmed = true ) as total_points"),
DB::raw("(SELECT SUM(price) FROM collections
WHERE paid_at IS NOT NULL
AND refunded_at IS NULL
AND collections.user_id = users.id) as total_purchase"),
DB::raw("(SELECT SUM(collections.price)) as current_purchase"))
->where("total_purchase", '>=', $min);
// other relevant code here
$query->groupBy('users.id')->orderBy('users.created_at', 'desc');
->where("total_purchase",">=", $min);
In the quick view, you did not put "," in the last line
FIXED:
Apparently, SELECT does not take multiple args but it accepts an array
->select(["users.*",
DB::raw("(SELECT SUM(amount) FROM points_history
WHERE points_history.user_id = users.id
AND points_history.confirmed = true ) as total_points"),
DB::raw("(SELECT SUM(price) FROM collections
WHERE paid_at IS NOT NULL
AND refunded_at IS NULL
AND collections.user_id = users.id) as total_purchase"),
DB::raw("(SELECT SUM(collections.price)) as current_purchase")]
Also ended up changing the WHERE clause to
$query->whereRaw(DB::raw("(SELECT SUM(amount) FROM points_history
WHERE points_history.user_id = users.id
AND points_history.confirmed = true ) <= " . $max));
with a dot instead of a comma to concatenate to the query

How can i convert this SQL to Laravel eloquent?

I have the following SQL
SELECT C.CUOCODE, C.NAME, COUNT(*) TOTAL_PAYMENT, SUM(P.AMOUNT) TOTAL_AMOUNT
FROM TAX_PAYMENT P
INNER JOIN TAX_CHECKPOINT C ON C.CUOCODE = REGEXP_SUBSTR(P.INVOICEID, 'R....')
WHERE DELETED = 0 AND TO_CHAR(TXTIME,'YYYY-MM-DD') = '2018-04-24'
GROUP BY C.CUOCODE, C.NAME
ORDER BY TOTAL_AMOUNT DESC;
How can i convert to laravel eloquent, i have "Payment" model (table TAX_PAYMENT) with "paymentid" as primary key.
DB::table('TAX_PAYMENT as P')
->select([
'C.CUOCODE',
'C.NAME',
DB::raw('COUNT(*) AS TOTAL_PAYMENT'),
DB::raw('SUM(P.AMOUNT) AS TOTAL_AMOUNT'),
])->Join('TAX_CHECKPOINT C', 'C.CUOCODE', '=', DB::raw('REGEXP_SUBSTR(P.INVOICEID,'R....')'))
->where('DELETED', 0)
->where(DB::raw("TO_CHAR(TXTIME,'YYYY-MM-DD')"), '2018-04-24')
->groupBy('C.CUOCODE')
->groupBy('C.NAME')
->orderBy('TOTAL_AMOUNT', 'desc')
->toSql();
output
SELECT
`C`.`CUOCODE`,
`C`.`NAME`,
COUNT(*) AS TOTAL_PAYMENT,
SUM(P.AMOUNT) AS TOTAL_AMOUNT
FROM
`TAX_PAYMENT` AS `P`
INNER JOIN `TAX_CHECKPOINT C` ON `C`.`CUOCODE` = REGEXP_SUBSTR (P.INVOICEID,"R....")
WHERE
`DELETED` = ?
AND TO_CHAR (TXTIME, 'YYYY-MM-DD') = ?
GROUP BY
`C`.`CUOCODE`,
`C`.`NAME`
ORDER BY
`TOTAL_AMOUNT` DESC
A quick and dirty way would be to use Eloquents select raw like:
$result = DB::select( DB::raw("SELECT C.CUOCODE, C.NAME, COUNT(*)
TOTAL_PAYMENT, SUM(P.AMOUNT) TOTAL_AMOUNT FROM TAX_PAYMENT INNER JOIN
TAX_CHECKPOINT C ON C.CUOCODE
= REGEXP_SUBSTR(P.INVOICEID, 'R....') WHERE DELETED = 0 AND
TO_CHAR(TXTIME,'YYYY-MM-DD') = '2018-04-24' GROUP BY C.CUOCODE,
C.NAME ORDER BY TOTAL_AMOUNT DESC"));

How to Convert this sql query into laravel query builder

select t.product_id,t.on_hand,t.created_at
from table t,
(SELECT MAX(purchase_id) as pId FROM table Group by product_id) tg
where t.purchase_id = tg.pId
$result = DB::table('table as t')
->select('t.product_id', 't.on_hand', 't.created_at')
->join(DB::raw('(SELECT MAX(purchase_id) as pId FROM table Group by product_id) tg'), function($join) {
$join->on('t.purchase_id', '=', 'tg.pId');
})->get();

Categories