Laravel combined OR AND Solution - php

I need to do select as the following
select * from table where (x = 1 OR y = 1) AND starting_at < '2018-05-01'
How to do that please.

DB::table('tableName')
->where(function ($query) {
$query->where('x', '=', 1)
->orWhere('y', '=', '1');
})
->where('starting_at', '<', '2018-05-01')
->get();

Related

How to write below query in Laravel

I have a table and there are two columns.
user_id
to_user_id
101
102
102
101
101
105
In the above table, 1 and 2 rows of users are like each other I want to remove 2 rows.
Here is my code.
$query = \App\Models\MyMatch::query();
$query->whereHas('users')->whereHas('tousers')
->select('my_matches.*')->distinct()
->where('user_id', '!=', 'to_user_id');
$records = $query->get();
In the above code, I got total 3 rows
I want only a total of 2 rows 1 and 3
So, how can I write a query for it
$records = \App\Models\MyMatch::whereHas('users')->whereHas('tousers')
->where(function($query) {
$query->where('user_id', '!=', 'to_user_id')
->orWhere(function($query) {
$query->where('user_id', '<', 'to_user_id');
});
})
->distinct()
->get();
or use a subquery :
$subquery = DB::table('my_matches')
->select('user_id', 'to_user_id')
->whereColumn('user_id', '>', 'to_user_id')
->toSql();
$records = \App\Models\MyMatch::whereHas('users')->whereHas('tousers')
->whereNotExists(function($query) use ($subquery) {
$query->select(DB::raw(1))
->from(DB::raw("($subquery) as sub"))
->whereRaw('my_matches.user_id = sub.to_user_id and my_matches.to_user_id = sub.user_id');
})
->get();
You can use
$query = \App\Models\MyMatch::query();
$query->whereHas('users')->whereHas('tousers')
->select('my_matches.*')
->where('user_id', '!=', 'to_user_id')
->groupBy('to_user_id')
->havingRaw('COUNT(*) = 1');
$records = $query->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();

Receive data per month with Laravel

I'am trying to create a morrisJS line chart that shows data per month.
So i get the data per month like this:
$intakes = Intakes::whereYear('created_at', '=', 2018)
->orWhere(function ($query) {
$query->whereMonth('created_at', '=', 1)
->whereMonth('created_at', '=', 2)
->whereMonth('created_at', '=', 3)
->whereMonth('created_at', '=', 4)
->whereMonth('created_at', '=', 5)
->whereMonth('created_at', '=', 6)
->whereMonth('created_at', '=', 7)
->whereMonth('created_at', '=', 8)
->whereMonth('created_at', '=', 9)
->whereMonth('created_at', '=', 10)
->whereMonth('created_at', '=', 11)
->whereMonth('created_at', '=', 12);
})
->get();
But that would return all the records, in the range from month 1 to 12. But what i want is the data per month, can this be achieved apart from just creating multiple variables like this ?
$intakesMonth1 = Intakes::whereYear('created_at', '=', 2018)
->whereMonth('created_at', '=', 1)
->get();
$intakesMonth2 = Intakes::whereYear('created_at', '=', 2018)
->whereMonth('created_at', '=', 2)
->get();
I hope that i'm clear enough and someone knows a better solution.
If you want an Eloquent solution, use whereMonth():
for($i = 1; $i < 13; $++) {
$intakes[$i] = Intakes::whereMonth('created_at', $i)->get();
}
You can also, get all intakes for the year and then use where() Laravel Collections method to get intakes for one month only:
$oneMonthData = $collection->where('created_at', '>', Carbon::parse($someDateString)->startOfMonth())->where('created_at', '<', Carbon::parse($someDateString)->endOfMonth());
$intakes = Intakes::whereDate('created_at', '<=', '01-01-2018 00:00:00')->whereDate('created_at', '<=', '01-02-2018 23:59:59')->get();

laravel 5.2 nested Where clause

How to perform a where clause using laravel eloquent with the following query:
select * from stats where payed = 1 AND WHERE (user_id = 1 OR owner_id = 1)
I don't know how to modify this code for this:
$payouts = Stat::where('payed', '1')
->???(function ($query) {
$query->where('owner_id', Auth::user()->id)
->where('user_id', Auth::user()->id);
})->get();
Change like this
$payouts = Stat::where('payed', '1');
$payouts->where(function ($payouts) {
$payouts->where('owner_id', Auth::user()->id)
->orWhere('user_id', Auth::user()->id);
})->get();
Try this
$payouts = Stat::where('payed', '1')
->where(function ($query) {
$query->where('owner_id', Auth::user()->id)
->orwhere('user_id', Auth::user()->id);
})->get();
You're close, this should do the trick:
$payouts = Stat::where('payed', '1')
->where(function ($query) {
$query->where('owner_id', Auth::user()->id)
->orWhere('user_id', Auth::user()->id);
})->get();
This is looking for where payed = 1 AND (owner_id is the current user ID OR the user_id is the current user ID)

Laravel Eloquent, return rows where both conditions are True

I have a table of Weeks that is joined to a property table, Weeks table looking like this:-
PropID, WeekDate, Available
1 , 2015-07-04, Yes
1 , 2015-07-11, Yes
1 , 2015-07-18, No
2 , 2015-07-04, Yes
2 , 2015-07-11, No
2 , 2015-07-18, No
I want to select properties where both the weeks of the 4th and 11th are available. In the example above, I want to return two rows with PropID 1 as both are available and no rows from PropID 2 as only one of the weeks are available.
I've tried various ways, but either get nothing or always return the 1st, 2nd and 4th rows.
I think this is close, but it's still missing something as it is looking for dates that are <= AND >=
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->where(function($sub)
{
$sub->where('WeekDate', '>=', '2015-07-04');
$sub->where('WeekDate', '<=', '2015-07-11');
});
$q->where('Available', '=', 'Yes');
})
->get();
Not sure this helps, but the Property table is simply
PropID, PropName
1 , Property 1
2 , Property 2
Just found that this SQL works.
SELECT PropID FROM tblweeks WHERE WeekDate IN ('2015-07-04', '2015-07-11') AND Available = 'yes' GROUP BY PropID HAVING COUNT(*) = 2
This will give your result as Property 1 only:
$weeks = Property::whereHas('Week', function ($q) {
$q->where(function ($sub) {
$sub->whereIn('WeekDate', array('2015-07-04', '2015-07-11'));
$sub->where('Available', '=', 'y');
});
$q->groupBy('property_id');
$q->having('count(*)', '=', '2');
})->get();
There are some changes i have did in your query :
Please check this solution
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->where('WeekDate', '=', '2015-07-04');
$q->orWhere('WeekDate', '=', '2015-07-11');
$q->where('Available', '=', 'Yes');
})
->get();
This should work and will return desire output
There are some changes, the query might be using group by query :
Please check this solution
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->where('WeekDate', '=', '2015-07-04');
$q->orWhere('WeekDate', '=', '2015-07-11');
$q->where('Available', '=', 'Yes');
$q->group('WeekDate');
})
->get();
This should work and will return desire output
You actually need two whereHas for this:
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->where('WeekDate', '>=', '2015-07-04');
$q->where('Available', '=', 'Yes');
})
->whereHas('Week', function($q) use ($arrive)
{
$q->where('WeekDate', '<=', '2015-07-11');
$q->where('Available', '=', 'Yes');
})
->get();
I believe you do not need the second nested query.
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->where('WeekDate', '>=', '2015-07-04');
$q->where('WeekDate', '<=', '2015-07-11');
$q->where('Available', '=', 'Yes');
})
->get();
Updated
Have you looked into whereBetween.
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->whereBetween('WeekDate', '2015-07-04', '2015-07-11');
$q->where('Available', '=', 'Yes');
})
->get();

Categories