How to convert query mysql to laravel query - php

Hai all I have this raw query in mysql I need to translate to laravel 5.4 query builder:
SELECT MONTH(calendar.datefield) AS Bulan, calendar.datefield AS Tanggal, IFNULL(SUM(dbk.jumlah),0) AS Jumlah
FROM detail_brg_keluar AS dbk
INNER JOIN penjualan AS pen ON pen.id = dbk.id_brg_keluar
RIGHT JOIN calendar ON (DATE(pen.tgl_keluar) = calendar.datefield)
WHERE
(calendar.datefield BETWEEN
(SELECT MIN(DATE(tgl_keluar)) FROM penjualan AS p
INNER JOIN detail_brg_keluar AS detail ON p.id = detail.id_brg_keluar
WHERE detail.id_produk = 818002)
AND
(SELECT MAX(DATE(tgl_keluar)) FROM penjualan AS pe
INNER JOIN detail_brg_keluar AS det ON pe.id = det.id_brg_keluar
WHERE det.id_produk = 818002))
AND (dbk.id_produk = 818002 OR dbk.id_produk IS NULL)
GROUP BY MONTH(calendar.datefield)
ORDER BY calendar.datefield ASC
This my laravel code, and code error -_-
$proT = DB::table('detail_brg_keluar AS dbk')
->select( DB::raw('MONTH(calendar.datefield) AS Bulan, calendar.datefield AS Tanggal, IFNULL(SUM(dbk.jumlah),0) AS Jumlah '))
->join('penjualan AS pen', 'pen.id', '=', 'dbk.id_brg_keluar')
->join('calendar', DB::raw('DATE(pen.tgl_keluar)'), '=', 'calendar.datefield')
->whereBetween('calendar.datefield', [$from[0]->tanggalAwal, $to[0]->tanggalAkhir])
->where(DB::raw('dbk.id_produk = 818002 OR dbk.id_produk IS NULL'))
->groupBy(DB::raw('MONTH(calendar.datefield)'))
->orderBy(DB::raw('calendar.datefield', 'ASC'))
->get();
Code from and to :
$from = DB::table('penjualan AS p')
->select(DB::raw('MIN(DATE(tgl_keluar)) AS tanggalAwal'))
->join('detail_brg_keluar AS detail', 'p.id', '=', 'detail.id_brg_keluar')
->where('detail.id_produk', $id)
->get();
$to = DB::table('penjualan AS p')
->select(DB::raw('MAX(DATE(tgl_keluar)) AS tanggalAkhir'))
->join('detail_brg_keluar AS detail', 'p.id', '=', 'detail.id_brg_keluar')
->where('detail.id_produk', $id)
->get();
I have no idea anymore?
Thx all

Use this:
$from = DB::table('penjualan AS p')
->select(DB::raw('MIN(DATE(tgl_keluar)) AS tanggalAwal'))
->join('detail_brg_keluar AS detail', 'p.id', '=', 'detail.id_brg_keluar')
->where('detail.id_produk', $id);
$to = DB::table('penjualan AS p')
->select(DB::raw('MAX(DATE(tgl_keluar)) AS tanggalAkhir'))
->join('detail_brg_keluar AS detail', 'p.id', '=', 'detail.id_brg_keluar')
->where('detail.id_produk', $id);
$proT = DB::table('detail_brg_keluar AS dbk')
->select( DB::raw('MONTH(calendar.datefield) AS Bulan, calendar.datefield AS Tanggal, IFNULL(SUM(dbk.jumlah),0) AS Jumlah '))
->join('penjualan AS pen', 'pen.id', '=', 'dbk.id_brg_keluar')
->rightJoin('calendar', DB::raw('DATE(pen.tgl_keluar)'), '=', 'calendar.datefield')
->whereRaw('calendar.datefield BETWEEN ('.$from->toSql().') AND ('.$to->toSql().')', [$id, $id])
->where(function($query) {
$query->where('dbk.id_produk', 818002)->orWhereNull('dbk.id_produk');
})
->groupBy(DB::raw('MONTH(calendar.datefield)'))
->orderBy('calendar.datefield', 'ASC')
->get();
Don't execute $from and $to, use the generated SQL.
I replaced ->join('calendar' with ->rightJoin('calendar'.
I replaced where(DB::raw()) with a nested constraint.
orderBy() doesn't need a raw expression.

Related

Eloquent query with COALESCE, IF, complex ON clause

i'd like to ask, how would you write the following query in Laravel Eloquent?
Please note the COALESCE, IF, and the complex LEFT JOIN ... ON (... AND ...).
SELECT COALESCE(IF(customer_group_id=6, prices.price, NULL), products.price) AS finalPrice, prices.customer_group_id, products.*, product_translations.*
FROM `product_categories`
LEFT JOIN `products` ON `product_categories`.`product_id` = `products`.`id`
LEFT JOIN `product_translations` ON `product_translations`.`product_id` = `products`.`id`
LEFT JOIN `prices`
ON (`products`.`id` = `prices`.`product_id` AND `prices`.`customer_group_id` = 6 )
WHERE `product_translations`.`locale` = 'it'
AND `products`.`online` = 1
AND `products`.`sellable` = 1
AND `category_id` = 22
UPDATE: By far, what i came up with is the following:
ProductCategory::leftjoin('products', 'product_categories.product_id', '=', 'products.id')
->leftJoin('product_translations', 'product_translations.product_id', 'products.id')
->leftJoin('prices', function($join) use($customer_group_id) {
$join->on('products.id', '=', 'prices.product_id')
->on('prices.customer_group_id', '=', DB::raw($customer_group_id));
})
->select(
DB::raw('coalesce(if(customer_group_id='.$customer_group_id.',prices.price,NULL), products.price) AS finalPrice'),
'prices.customer_group_id',
'products.*',
'product_translations.*'
)
->where('product_translations.locale', '=', $locale)
->where('products.online', '=', true)
->where('products.sellable', '=', true)
->where('category_id', '=', $this->id);

how to turn Aggregates with multiple table into USE DB at laravel?

How can I write the query like that on Laravel, btw I'm using DB
I followed this instruction
https://dba.stackexchange.com/questions/175786/join-multiple-tables-for-aggregates, but still not get it
mysql query:
SELECT inptkegiatan.IDKEGIATAN,
(SELECT COUNT(kuesioner.PERTANYAAN)
FROM kuesioner
WHERE inptkegiatan.IDKEGIATAN = kuesioner.IDKEGIATAN) as totalPertanyaan,
(SELECT SUM(hasilkuesioner.JAWABAN)
FROM hasilkuesioner
WHERE kuesioner.IDKEGIATAN = hasilkuesioner.IDKEGIATAN) as totalJawaban,
(SELECT COUNT(regiskegiatan.IDKEGIATAN)
FROM regiskegiatan
WHERE hasilkuesioner.IDKEGIATAN = regiskegiatan.IDKEGIATAN ) as totalUser
FROM inptkegiatan
LEFT JOIN kuesioner ON inptkegiatan.IDKEGIATAN = kuesioner.IDKEGIATAN
LEFT JOIN hasilkuesioner ON inptkegiatan.IDKEGIATAN = hasilkuesioner.IDKEGIATAN
LEFT JOIN regiskegiatan ON inptkegiatan.IDKEGIATAN = regiskegiatan.IDKEGIATAN
GROUP BY inptkegiatan.IDKEGIATAN
I tried this on my Laravel with that url, still not get it
$datatwo = DB::table('inptkegiatan')
->join('kuesioner', 'inptkegiatan.IDKEGIATAN', '=', 'kuesioner.IDKEGIATAN')
->join('hasilkuesioner', 'inptkegiatan.IDKEGIATAN', '=', 'hasilkuesioner.IDKEGIATAN')
->join('regiskegiatan', 'inptkegiatan.IDKEGIATAN', '=', 'regiskegiatan.IDKEGIATAN')
->where('IDNARASUMBER', '=', $value->PROFILEUSERS_ID)
->select('kuesioner.PERTANYAAN', 'hasilkuesioner.*', 'regiskegiatan.*',
DB::raw('count(DISTINCT(kuesioner.IDKEGIATAN)) + SUM(DISTINCT(hasilkuesioner.IDKEGIATAN)) as articles')
)
->groupBy('inptkegiatan.IDKEGIATAN')
->get();
First of all, use leftJoin instead of join, because join is alternate for innerJoin
$datatwo = DB::table('inptkegiatan')
->leftJoin('kuesioner', 'inptkegiatan.IDKEGIATAN', '=', 'kuesioner.IDKEGIATAN')
->leftJoin('hasilkuesioner', 'inptkegiatan.IDKEGIATAN', '=', 'hasilkuesioner.IDKEGIATAN')
->leftJoin('regiskegiatan', 'inptkegiatan.IDKEGIATAN', '=', 'regiskegiatan.IDKEGIATAN')
->where('inptkegiatan.IDNARASUMBER', '=', $value->PROFILEUSERS_ID)
->select([
'inptkegiatan.IDKEGIATAN',
\DB::raw('SELECT COUNT(kuesioner.PERTANYAAN)
FROM kuesioner
WHERE inptkegiatan.IDKEGIATAN = kuesioner.IDKEGIATAN) as totalPertanyaan'),
\DB::raw('(SELECT SUM(hasilkuesioner.JAWABAN)
FROM hasilkuesioner
WHERE kuesioner.IDKEGIATAN = hasilkuesioner.IDKEGIATAN) as totalJawaban'),
\DB::raw('(SELECT COUNT(regiskegiatan.IDKEGIATAN)
FROM regiskegiatan
WHERE hasilkuesioner.IDKEGIATAN = regiskegiatan.IDKEGIATAN ) as totalUser')
])
->groupBy('inptkegiatan.IDKEGIATAN')
->get();
Try with this. It should work

How to convert a specific query into Laravel Query syntax

I'm trying to change the following query to laravel :
SELECT
*
FROM
usrusrs uu
,posts p
WHERE
(
uu.user_id = $u_id
or
uu.friend_id = $u_id
)
and
(
uu.user_id = p.user_id
OR
uu.friend_id = p.user_id
)
I tried the following, but it's giving different output. I think there might be something wrong with the joining between the two tables. any suggestions ?
$usrusrmembs = DB::table('usrusrs')
->join('posts', 'posts.user_id', '=', 'usrusrs.user_id')
->orwhere('posts.user_id', '=', 'usrusrs.friend_id')
->where('usrusrs.user_id', $u_id)
->orwhere('usrusrs.friend_id', $u_id)
->get();
Got it after some digging :
$usrusrmembs = DB::table('usrusrs')
->join('posts', function ($join) {
$join->on('posts.user_id', '=', 'usrusrs.user_id')->orOn('posts.user_id', '=', 'usrusrs.friend_id');
})
->where('usrusrs.user_id', $u_id)
->orwhere('usrusrs.friend_id', $u_id)
->get();

How to write a subquery in Laravel query builder

i have an mssql query that looks like this:
SELECT * FROM (
SELECT a.Client, ad.Kto, a.Address, a.Matchcode, a.Name1, a.country, a.ZIP, a.Street FROM [HeadQuarter].[dbo].[Addresses] a
INNER JOIN [HeadQuarter].[dbo].[AddressesDetails] ad ON (a.Client = ad.Client AND
a.Address = ad.Address)
WHERE ad.Active <> 0 AND
(a.USER_emailactive = 0 OR a.USER_emailactive IS NULL)
) client_id
WHERE (a.Country = 'AT' AND a.ZIP BETWEEN '0000' AND '5000')
i converted the inner select into Laravel query builder
\DB::connection('sqlsrv')
->table('[HeadQuarter].[dbo].[Addresses]')
->join([HeadQuarter].[dbo].[AddressesDetails], function($join){
$join->on('[HeadQuarter].[dbo].[Addresses].Client', '=', '[HeadQuarter].[dbo].[AddressesDetails].Client')
->on('[HeadQuarter].[dbo].[Addresses].Address', '=', '[HeadQuarter].[dbo].[AddressesDetails].Address')
})
->select('[HeadQuarter].[dbo].[Addresses].Client, [HeadQuarter].[dbo].[AddressesDetails].Kto,....')
->where('[HeadQuarter].[dbo].[AddressesDetails].Active', '<>', '0')
->whereRaw('(a.USER_emailactive = 0 OR a.USER_emailactive IS NULL)')
->get();
and this is working. But now how can i get the
SELECT * FROM (..inner query..) client_id
WHERE (a.Country = 'AT' AND a.ZIP BETWEEN '0000' AND '5000')
convert to my query builder. sure i could use ->select() and write the raw sql query but i need this in the query builder because my inner and outer where clause i optional
I guess you could simplify your query as below, there is not need for sub query
SELECT a.Client, ad.Kto, a.Address, a.Matchcode, a.Name1, a.country, a.ZIP, a.Street
FROM [HeadQuarter].[dbo].[Addresses] a
INNER JOIN [HeadQuarter].[dbo].[AddressesDetails] ad
ON (a.Client = ad.Client AND a.Address = ad.Address)
WHERE ad.Active <> 0
AND a.Country = 'AT'
AND a.ZIP BETWEEN '0000' AND '5000'
AND (a.USER_emailactive = 0 OR a.USER_emailactive IS NULL)
In query builder you can use Parameter Grouping
\DB::connection('sqlsrv')
->table('[HeadQuarter].[dbo].[Addresses] as a')
->join('[HeadQuarter].[dbo].[AddressesDetails] as b', function($join){
$join->on('a.Client', '=', 'ad.Client')
->on('a.Address', '=', 'ad.Address');
})
->select('a.Client', 'ad.Kto', 'a.Address', 'a.Matchcode', 'a.Name1', 'a.country', 'a.ZIP', 'a.Street')
->where('ad.Active', '<>', '0')
->where(function ($query) {
$query->whereNull('a.USER_emailactive')
->orWhere('a.USER_emailactive', '=', '0');
})
->where(function ($query) {
$query->orWhere(function ($query) {
$query->where('a.Country', '<>', 'AT')
->whereBetween('a.ZIP', ['0000', '5000']);
})->orWhere(function ($query) {
$query->where('a.Country', '<>', 'Foo')
->whereBetween('a.ZIP', ['0000', '5000']);
})->orWhere(function ($query) {
$query->where('a.Country', '<>', 'Bar')
->whereBetween('a.ZIP', ['0000', '5000']);
});
})
->get();

Passing parameter bindings to Laravel query builder?

I currently have a SQL query which a fantastic stackoverflow member helped me with earlier today. At the moment it works absolutely fine and the way I want it to work.
The only problem is it's RAW SQL and I'd very much like to get this working with the Laravel Query Builder.
SORRY THIS IS AN EDIT - HERE IS THE ORIGINAL QUERY:
$addresses = DB::select(
DB::raw('
(SELECT
"Company" AS object_type_name,
companies.company_name AS object_name,
addresses.*
FROM
addresses
INNER JOIN
companies
ON
addresses.object_id = companies.id
WHERE
addresses.object_type = 2)
UNION ALL
(SELECT
"Job" AS object_type_name,
jobs.job_title AS object_name,
addresses.*
FROM
addresses
INNER JOIN
jobs
ON
addresses.object_id = jobs.id
WHERE
addresses.object_type = 4)
'));
Here is the code I have so far:
$bindings = array(
'soft_deleted' => 0,
'user' => 1,
'company' => 2,
'candidate' => 3,
'job' => 4,
);
$companies = DB::table('addresses')->select(
'addresses.*',
'companies.company_name as object_name'
)->where('addresses.soft_deleted', '=', 0)->join('companies', function($join) use ($bindings){
$join->on('addresses.object_id', '=', 'companies.id')
->where('addresses.object_type', '=', $bindings['company']);
});
$jobs = DB::table('addresses')->select(
'addresses.*',
'jobs.job_title as object_name'
)->join('jobs', function($join) use ($bindings){
$join->on('addresses.object_id', '=', 'jobs.id')
->where('addresses.object_type', '=', $bindings['job']);
});
$addresses = $companies->unionAll($jobs)->get();
With the code above I'm getting the following error:
SQLSTATE[HY093]: Invalid parameter number (SQL: (select addresses., companies.company_name as object_name from addresses inner join companies on addresses.object_id = companies.id and addresses.object_type = 2 where addresses.soft_deleted = 0) union all (select addresses., jobs.job_title as object_name from addresses inner join jobs on addresses.object_id = jobs.id and addresses.object_type = ?))
I've done hours worth of searching but I can't seem to find the answer to this little problem.
I managed to fix it. It was as simple as removing the ->where from within each join closure and chaining it to the join itself and not nesting it.
Before:
$companies = DB::table('addresses')->select(
'addresses.*',
'companies.company_name as object_name'
)->where('addresses.soft_deleted', '=', 0)->join('companies', function($join) use ($bindings){
$join->on('addresses.object_id', '=', 'companies.id')
->where('addresses.object_type', '=', $bindings['company']);
});
$jobs = DB::table('addresses')->select(
'addresses.*',
'jobs.job_title as object_name'
)->join('jobs', function($join) use ($bindings){
$join->on('addresses.object_id', '=', 'jobs.id')
->where('addresses.object_type', '=', $bindings['job']);
});
After:
$companies = DB::table('addresses')->select(
'addresses.*',
'companies.company_name as object_name'
)->where('addresses.soft_deleted', '=', 0)->join('companies', function($join){
$join->on('addresses.object_id', '=', 'companies.id');
})->where('addresses.object_type', '=', 2);
$jobs = DB::table('addresses')->select(
'addresses.*',
'jobs.job_title as object_name'
)->where('addresses.soft_deleted', '=', 0)->join('jobs', function($join){
$join->on('addresses.object_id', '=', 'jobs.id');
})->where('addresses.object_type', '=', 4);
$addresses = $companies->unionAll($jobs)->get();
Hope this helps someone.

Categories