How to convert SELECT statement to Eloquent? - laravel-5

This works in existing website, trying to convert to Laravel 5.8 code:
SELECT
DATE_FORMAT(created_at, '%M %Y') AS 'article',
DATE_FORMAT(created_at, '%m')AS 'm',
DATE_FORMAT(created_at,'%Y') AS 'y',
COUNT(id) AS 'total'
FROM posts
GROUP BY DATE_FORMAT(created_at, '%Y%M')
ORDER BY m DESC
I tried:
$archives = DB::select("SELECT DATE_FORMAT(created_at, '%M %Y') AS 'article',DATE_FORMAT(created_at, '%m')AS 'm', DATE_FORMAT(created_at,'%Y') AS 'y', COUNT(id) AS 'total' FROM posts GROUP BY DATE_FORMAT(created_at, '%Y%M') ORDER BY m DESC");`
I got:
Error: SQLSTATE[42000]: Syntax error or access violation: 1055
'amohdb.posts.created_at' isn't in GROUP BY (SQL: SELECT
DATE_FORMAT(created_at, '%M %Y') AS 'article',DATE_FORMAT(created_at,
'%m')AS 'm', DATE_FORMAT(created_at,'%Y') AS 'y', COUNT(id) AS 'total'
FROM posts GROUP BY DATE_FORMAT(created_at, '%Y%M') ORDER BY m DESC)

Answer turned out to be much simpler than I thought
$archives = Post::select(DB::raw("DATE_FORMAT(created_at, '%M %Y') as article"),
DB::raw("COUNT(id) as total"))
->groupBy('article')
->get();

Related

How to group by with union in laravel

I have two table that I want to union and after I union them I want to groupBy the one column that I used in union
Here is what I tried:
$issuance = DB::table('issuance as i')
->select('i.issue_to as stud_id', 'i.created_on');
$stud= DB::table('transfer as t')
->select('t.transfer_to as stud_id', 't.created_on')
->union($issuance)
->select('stud_id', 'created_on', DB::raw('COUNT(*) as total_asset'))
->groupBy('stud_id')
->orderBy('created_on', 'DESC')->get();
This is the MySQL query in what I tried
"(select `stud_id`, `created_on`, COUNT(*) as total_asset from `transfer` as
`t` group by `stud_id`) union (select `i`.`issued_to` as `stud_id`, `i`.`created_on` from
`issuance` as `i`) order by `created_on` desc"
What I really want in MySQL is like this:
select stud_id, count(*) from ((select `t`.`transfered_to` as `stud_id`,
`t`.`created_on` from `transfer` as `t`) union (select `i`.`issued_to` as
`stud_id`, `i`.`created_on`, COUNT(*) as asset from `issuance` as `i`)) as t
group by stud_id order by `created_on` desc
Thank you for the help
//try this example ,it will helps you
$query1 = DB::table('table1')->where(....);
$query2 = DB::table('table2')->where(....);
$data = DB::select(DB::raw('id, MAX(created_at) as max_created_at')>union($query1)->union($query2)->orderBy('max_created_at')->groupBy('id')->get();

How can I convert mysql to laravel eloquent left join?

Mysql query like this :
SELECT a.id, a.name, b.TotalMeal, c.TotalCollection
FROM users a
LEFT JOIN (
SELECT user_id, SUM( breakfast + dinner + lanch ) AS TotalMeal
FROM meals
GROUP BY user_id) b ON a.id = b.user_id
LEFT JOIN (
SELECT user_id, SUM( amount ) AS TotalCollection
FROM collections
GROUP BY user_id) c ON a.id = c.user_id
LIMIT 0, 30
I want to convert it to Laravel eloquent, but I'm confused. I have Three tables. eg - users( id, name,email ..), meals( user_id, breakfast,lanch,dinner) and collections(user_id, amount) .
There is a little hack that uses withCount() to select sums of related tables which can be used in your scenario:
User::query()
->select([
'id',
'name',
])
->withCount([
'meals as total_meals' => function ($query) {
$query->select(DB::raw('SUM(breakfast + dinner + lunch)'));
},
'collections as total_collections' => function ($query) {
$query->select(DB::raw('SUM(amount)'));
},
])
->get();
In this query, withCount will perform the joins for you.

How to join on a select result with eloquent in Laravel?

I want to join on a result of other select like this :
SELECT *
FROM TABLE1
JOIN (
SELECT cat_id FROM TABLE2 where brand_id = 2 GROUP BY TABLE2.cat_id) AS b ON TABLE1.id = b.cat_id
is there any way to do this with eloquent?
As it is mentioned here, using DB:raw() will solve your problem.
DB::table('table1')->join(DB::raw("(SELECT
cat_id
FROM table2
WHERE brand_id = 2
GROUP BY table2.cat_id
) as b"),function($join){
$join->on("b.cat_id","=","table1.id");
})->get();
\DB::table('table1')->join('table2' , function($join){
$join->on('table1.id', '=', 'table2.cat_id');
})->select(['table2.cat_id' , 'table1.*'])
->where('table2.brand_id' , '=' , '2')
->groupBy('table2.cat_id');
Depends on whether brand_id is in table1 or table2
You can also use model approach for it.
TABLE1::join('table2' , function($join){
$join->on('table1.id', '=', 'table2.cat_id');
})->select(['table2.cat_id' , 'table1.*'])
->where('table2.brand_id' , '=' , '2')
->groupBy('table2.cat_id');

ORA-32033: unsupported column aliasing

I have a query that is working on oracle 12c but not in 10g. I am not sure what the problem is:
My query is:
WITH tab1(rn,begin_chq_num,chq_lvs_stat,chq_num_of_lvs,tes) AS
(SELECT 1 rn,
begin_chq_num,
chq_lvs_stat,
chq_num_of_lvs,
SUBSTR(chq_lvs_stat,1,1) tes
FROM tbaadm.chq_book_table
WHERE del_flg != 'Y'
AND acid IN
(SELECT acid
FROM tbaadm.GENERAL_ACCT_MAST_TABLE
WHERE foracid = '01411110171546'
)
UNION ALL
SELECT rn + 1 rn,
begin_chq_num,
chq_lvs_stat,
chq_num_of_lvs,
SUBSTR(chq_lvs_stat,rn + 1,1) tes
FROM tab1
WHERE rn < chq_num_of_lvs
)
SELECT
CASE
WHEN begin_chq_num = 1
THEN rn
ELSE begin_chq_num +(rn-1)
END cheque_num,
begin_chq_num
||'-'
||(chq_num_of_lvs+begin_chq_num-1) cheque_range,
DECODE(tes, 'I', 'Issued', 'P', 'Cleared', 'U', 'Unused', 'S', 'Stopped', 'C', 'Cautioned', 'D', 'Destroyed', 'R', 'Returned Paid', 'T', 'Transfered') status
FROM tab1
ORDER BY chq_lvs_stat,
rn;
The error is :
ORA-32033: unsupported column aliasing
32033. 00000 - "unsupported column aliasing"
*Cause: column aliasing in WITH clause is not supported yet
*Action: specify aliasing in defintion subquery and retry
What should I do different?
In Oracle 10g, the sub-query factoring clause does not support column aliases or recursive sub-queries. The syntax you are using appears in 11gR2.
You need to change:
WITH tab1(rn,begin_chq_num,chq_lvs_stat,chq_num_of_lvs,tes) AS
To:
WITH tab1 AS
And find a different solution that does not use a recursive subquery factoring clause.
I think you could do this in Oracle 10g:
WITH tab1 AS (
SELECT l.COLUMN_VALUE rn,
begin_chq_num,
chq_lvs_stat,
chq_num_of_lvs,
SUBSTR(chq_lvs_stat,l.COLUMN_VALUE,1) tes
FROM tbaadm.chq_book_table t,
TABLE(
CAST(
MULTISET(
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= LENGTH( t.chq_lvs_stat )
)
AS SYS.ODCINUMBERLIST
)
) l
WHERE del_flg != 'Y'
AND acid IN ( SELECT acid
FROM tbaadm.GENERAL_ACCT_MAST_TABLE
WHERE foracid = '01411110171546'
)
)
SELECT CASE
WHEN begin_chq_num = 1
THEN rn
ELSE begin_chq_num +(rn-1)
END cheque_num,
begin_chq_num
||'-'
||(chq_num_of_lvs+begin_chq_num-1) cheque_range,
DECODE(
tes,
'I', 'Issued',
'P', 'Cleared',
'U', 'Unused',
'S', 'Stopped',
'C', 'Cautioned',
'D', 'Destroyed',
'R', 'Returned Paid',
'T', 'Transfered'
) status
FROM tab1
ORDER BY chq_lvs_stat, rn;

Oracle pivot query results in a "command not properly ended" error

When firing the following query to a 10g Oracle database:
SELECT * FROM (
SELECT T1.ID, T2.ACCT_NO, ROW_NUMBER() OVER (PARTITION BY T1.ID ORDER BY T1.ID DESC) AS RRRRRRR
FROM TABLE1 T1
INNER JOIN TABLE T2 ON T1.ID = T2.ID
WHERE T1.ID = 666
)
PIVOT (MIN(T1.ID) AS ALIAS1 FOR RRRRRRR IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
I get an "command not properly ended" error.
I've searched for Oracle pivot examples and they all pretty much showed the same example.
What am I missing here?
As #APC pointed out there is no PIVOT function in oracle 10g, so you can use an aggregate function and a CASE, similar to this:
SELECT id, acct_no,
min(case when RRRRRRR = 1 then id end) as '1',
min(case when RRRRRRR = 2 then id end) as '2',
min(case when RRRRRRR = 3 then id end) as '3',
min(case when RRRRRRR = 4 then id end) as '4',
min(case when RRRRRRR = 5 then id end) as '5',
min(case when RRRRRRR = 6 then id end) as '6',
min(case when RRRRRRR = 7 then id end) as '7',
min(case when RRRRRRR = 8 then id end) as '8',
min(case when RRRRRRR = 9 then id end) as '9',
min(case when RRRRRRR = 10 then id end) as '10'
FROM
(
SELECT T1.ID, T2.ACCT_NO, ROW_NUMBER() OVER (PARTITION BY T1.ID ORDER BY T1.ID DESC) AS RRRRRRR
FROM TABLE1 T1
INNER JOIN TABLE T2 ON T1.ID = T2.ID
WHERE T1.ID = 666
) x
GROUP BY id, acct_no
Your syntax is impeccable. Unfortunately PIVOT was introduced in Oracle 11g and you're using 10g.

Resources