how to use MIN and MAX sql query in Laravel Eloquent - mysql

i want to use min and max laravel elaquent at the same line, is that posible?
Appointmentsetting::where('Day','=',1)
->whereIn('PersonID', function ($query) {
$query->select('p.id')
->from('users as p')
->join('appointmentsettings as aps', 'aps.PersonID', '=', 'p.id')
->where('p.active', '=', 1)
->where('aps.CompanyID', '=', 1)
->orWhereIn('aps.PersonID', function ($query2) {
$query2->select('cps.user_id')
->from('companypersonstructs as cps')
->where('cps.CompanyID', '=', 1);
})
->groupBy('aps.PersonID');
})
->where('active', '=', 1)
->select(\DB::raw("SELECT MIN(StartFrom) AS StartFrom, MAX(EndTo) AS EndTo"));
->get();
i got error
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your
MariaDB server version for the right syntax to use near 'SELECT
MIN(StartFrom) AS StartFrom, MAX(EndTo) AS EndTo from
`appointmentsetting' at line 1

->selectRaw(" MIN(StartFrom) AS StartFrom, MAX(EndTo) AS EndTo");
please put above query and try. the main problem in your query is you are using select two time there is no need for write select inside select or selectRaw
for more about raw query click here

Appointmentsetting::where('Day','=',1)
->whereIn('PersonID', function ($query) {
$query->select('p.id')
->from('users as p')
->join('appointmentsettings as aps', 'aps.PersonID', '=', 'p.id')
->where('p.active', '=', 1)
->where('aps.CompanyID', '=', 1)
->orWhereIn('aps.PersonID', function ($query2) {
$query2->select('cps.user_id')
->from('companypersonstructs as cps')
->where('cps.CompanyID', '=', 1);
})
->groupBy('aps.PersonID');
})
->where('active', '=', 1)
->select(\DB::raw("MIN(StartFrom) AS StartFrom, MAX(EndTo) AS EndTo"));
->get();

Related

Laravel 5.4 Error when Joining two tables

I need to join two tables in laravel model. Here is my query,
$id="1002";
$resultsInCalls = DB::table('qlog')
->select('user_master.fname','user_master.lname','qlog.data2')
->whereDate('created', '=', date('Y-m-d')) // this day
->join('qlog', 'qlog.agent', '=', 'user_master.sip_id')
->where('agent', '=', $id)
->where(function ($query) {
$query->where('event', '=', 'COMPLETEAGENT')
->orWhere('event', '=', 'COMPLETECALLER');
})
->take(5)
->get();
But I run this query I get following error.
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'qlog' (SQL: select `user_master`.`fname`, `user_master`.`lname`, `qlog`.`data2` from `qlog` inner join `qlog` on `qlog`.`agent` = `user_master`.`sip_id` where date(`created`) = 2017-11-29 and `agent` = 1002 and (`event` = COMPLETEAGENT or `event` = COMPLETECALLER) limit 5)
I read related questions. But I can't figure it out. How to fix this error.
Here I get it done,
$resultsInCalls = DB::table('qlog')
->join('user_master as user_table', 'qlog.agent', '=', 'user_table.sip_id')
->select('user_table.fname','user_table.lname','qlog.data2')
->whereDate('created', '=', date('Y-m-d')) // this day
->where('agent', '=', $id)
->where(function ($query) {
$query->where('event', '=', 'COMPLETEAGENT')
->orWhere('event', '=', 'COMPLETECALLER');
})
->take(5)
->get();

Laravel join tables and concatenate rows

So I have two tables, organizations and contacts. Both tables have column "email", what I need to do is to keep the name of organization, but in email column concatenate all emails (organization's + all contact emails).
Here are some versions that I tried with no luck
1) this one doesn't group:
$customers = DB::table('customers')
->whereRaw('LENGTH(customers.email) > 4')
->select([
'customers.id',
'customers.name',
'customers.email'
]);
$contacts = DB::table('contacts')
->whereRaw('LENGTH(contacts.email) > 4')
->leftJoin('customers', 'contacts.customer_id', '=', 'customers.id')
->select([
'customers.id',
'customers.name',
'contacts.email'
]);
return $customers
->union($contacts)
->select([
'id',
'name',
DB::raw('GROUP_CONCAT(DISTINCT email, ", ") AS emails'),
])
->groupBy('id')
->get();
2) this one is actually pretty close, but it doesn't filter out entries where neither contact or customer entires have DB::raw('LENGTH(email) > 4')
return $customers = DB::table('customers')
->leftJoin('contacts', 'contacts.customer_id', '=', 'customers.id')
->select([
'customers.id',
'customers.name',
'registration',
DB::raw('GROUP_CONCAT(DISTINCT contacts.email, ", ") AS contact_emails'),
'customers.email'
])
->groupBy('customers.id')
->get();
3) I tried to get closer with subqueries (I know it would only filter out contacts with no emails)
3.1) Trying subquery 1 results in error: JoinClause::whereRaw() doesn't exist
return $customers = DB::table('customers')
->leftJoin('contacts', function($join) {
$join->on('contacts.customer_id', '=', 'customers.id')
->whereRaw('LENGTH(email) > 4');
})...
3.2) This one produces the syntax error below:
return $customers = DB::table('customers')
->leftJoin('contacts', function($join) {
$join->on('contacts.customer_id', '=', 'customers.id')
->where(DB::raw('LENGTH(email) > 4'));
})
1/2 PDOException in Connection.php line 333: SQLSTATE[42000]: Syntax
error or access violation: 1064 You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the
right syntax to use near '? group by customers.id' at line 1
2/2 QueryException in Connection.php line 713: SQLSTATE[42000]: Syntax
error or access violation: 1064 You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the
right syntax to use near '? group by customers.id' at line 1 (SQL:
select customers.id, customers.name, registration,
GROUP_CONCAT(DISTINCT contacts.email, ", ") AS contact_emails,
customers.email from customers left join contacts on
contacts.customer_id = customers.id and LENGTH(contacts.email)
4 group by customers.id)
3.3) some examples say I should do it this way, but this produces the error Not enough arguments for the on clause.
return $customers = DB::table('customers')
->leftJoin('contacts', function($join) {
$join->on('contacts.customer_id', '=', 'customers.id');
$join->on(DB::raw('LENGTH(contacts.email) > 4'));
})
This works for me. No syntax errors and filters out contacts with length less than 4 characters:
DB::table('customers')
->leftJoin('contacts', function ($join) {
$join->on('contacts.customer_id', '=', 'customers.id')
->where(DB::raw('length(contacts.email)'), '>', 4);
})
->select([
'customers.id',
'customers.name',
DB::raw('group_concat(distinct contacts.email separator ", ") AS contact_emails'),
])
->groupBy('customers.id')
->get();
Tested in Laravel 5.3.26, MySQL 5.6.20 (no strict mode).

Where clause on join query laravel 4.2

I have 2 tables 'users' and 'instantUsers'. I want to join them on users.id = instantUsers.user_id and want to add 2 where clauses on the resulting. I'm not getting how to do both. The query I'm using is -
DB::table('users')
->join('instantUsers', function($join) use ($userId) {
$join->on('users.id', '=', 'instantUsers.user_id');
})
->where('instantUsers.instantMode', '=', '1')
->where (function($query) use ($userId) {
$query->where('instantUsers.user_id', '!=', $userId);
})
->get();
You can try this one maybe this will help you:
DB::table('users as table1')->join('instantUsers as table2','table1.id','=','table2.fkId') ->where('table2.instantMode','=','1')->where('table2.user_id','!=',$userId)->get();
Your 'instantUsers.instantMode','=','1' expression can be done in a join, resulting in a better performance.
I would write it like this
DB::table('users')
->join('instantUsers', function($join) use ($userId) {
$join
->on('users.id', '=', 'instantUsers.user_id')
->on('instantUsers.instantMode', '=', 1);
})
->where('users.id', '!=', $userId)
->get();

WhereNotIn Subquery

What i'm trying to achieve is the following:
I want to check if there is a record with the same client_code but with a lower/different campaign id. I'm using a sub-query for now and i tried to do it with a join as well but I couldn't get the logic working
This is what i got now:
$oDB = DB::table('campaigns AS c')
->select(
'c.id AS campaign_id',
'cc.id AS campaign_customer_id'
)
->join('campaign_customers AS cc', 'cc.campaign_id', '=', 'c.id')
->where('c.status', '=', ModelCampaign::STATUS_PLANNED)
->where('c.scheduled', '=', 1)
->whereRaw('c.scheduled_at <= NOW()')
->where('cc.status', '=', ModelCampaignCustomer::STATUS_INVITE_EMAIL_SCHEDULED)
->whereNotIn('cc.client_code', '=', function ($query){
$query ->select(DB::raw(1))
->from('campaign_customers')
->whereRaw('campaign_id', '!=', 'c.id');
})
->where('cc.active', '=', 1)
;
any tips on how to work the logic would be great
You can use the ->toSql(); method to see the SQL so you can refactorize your query.
The whereNotIn probably shouldn't have an = in it
->whereNotIn('cc.client_code', function ($query){
....
edit
Try:
->whereNotIn('cc.client_code', function ($query){
$query->select(DB::raw('client_code'))
->from('campaign_customers')
->whereRaw('campaign_id != c.id');
})
I think the whereRaw should be a single text string or maybe you can use where here (looking at this for reference https://laravel.com/docs/5.2/queries#advanced-where-clauses). Also DB::raw(1) is going to return a 1 for each subquery result but you want an id for the whereNotIn.

Laravel Query Builder Nested Join and Alias

How to create this query using Laravel's Query Builder:
SELECT `content`.`tagable_id`,`taged`.`tag_id`
FROM `taged`
RIGHT JOIN
(SELECT `taged`.`tagable_id`,`taged`.`tag_id`
FROM `taged`
WHERE `taged`.`mask_flag`='0'
AND `taged`.`tagable_type`='App\\\Post'
AND `taged`.`user_id`='1') AS `content`
ON `taged`.`mask_flag`='1'
AND `content`.`tagable_id`=`taged`.`tagable_id`
AND `taged`.`tagable_type`='App\\\Post'
AND `taged`.`user_id`='1'
The parenthesis around the inner SELECT taged.tagable_id... is where my main problem lies.
Here is your Laravel query:
$result = DB::table('taged')
->select('content.tagable_id', 'taged.tag_id')
->rightJoin(DB::raw('SELECT tagable_id, tag_id FROM taged AS content'), function($join)
{
$join->on('taged.mask_flag', '=', 1);
$join->on('content.tagable_id', '=', 'taged.tagable_id');
$join->on('taged.tagable_type', '=', 'App\\\Post');
$join->on('taged.user_id', '=', 1);
})
->where('content.mask_flag', '=', 0);
->where('content.tagable_type', '=', 'App\\\Post');
->where('content.user_id', '=', 1);
->get();