Laravel使用不同的条件获得相同的查询

I have query below:

$address = Address::where('id', $request->input('address_id'))->first();
$state = $address->state_id;

$mytime = Carbon::now();
$mytax = Tax::where('province_id', $state)
  ->where('validation', '=', 'active')
  ->where('valid_to', '>=', $mytime)
  ->first();

This simply check my taxes table and if expired date hasn't reached yet returns data. It's working perfectly but the issue is that I have 2 conditions and this query only returns one of them.

Conditions

  1. Time based tax (query above)
  2. Permanent tax which doesn't rely on dates (that part I don't have yet)

Logic

  1. Find tax based on province_id (first part of my query)
  2. If no.1 passed, check validation column if is set to active means is time based and needs ->where('valid_to', '>=', $mytime) part if is set to inactive it's not time based and always should return the data (in case there is any in database)

Any idea how can I check validation column value before actually go for date validation?

I assume that the validation field may take two values. 'active' or 'inactive'.

This query will check two things. If the 'validation' is 'inactive' or the 'valid_to' is greater than today.

$mytax = Tax::where('province_id', $state)
            ->where(function($query) use ($mytime)) {
                   $query->where('validation', 'inactive')
                         ->orwhere('valid_to', '>=', $mytime);
                   })
            ->first();

I think I understand what you are trying to do. But, based on the logic you presented, I don't think the problem is a query issue, but rather an architecture tweak -- you said it yourself, you have two different conditions. And, I think you have two different queries; one is for one active record (->first()), the other is for all inactive records (->get()).

You can still just run one DB pull, but I think you need to separate out the logic into a conditional statement on that single DB pull:

$taxes = Tax::where('province_id', $state)->get();

Now that you have the taxes for that state, run the query on the collection to see if you need to pull the invalids:

$myTax = $taxes->where('validation', '=', 'active')
         ->where('valid_to', '>=', $mytime)
         ->first();

Then the conditional based on your original need:

if(!isset($myTax)){
    $myTax(es?) = $taxes->where('validation', '=', 'inactive);

This gives you potentially more than one, so you'll have to handle the difference between first() and a collection, but this would be one way to solve it.