仅将 where 条件应用于一次
Apply where condition only to one occurrence
我正在为我的应用构建搜索功能。为了简化事情:
有两个表:商店和订阅
每个店铺可以有多个订阅记录,订阅有字段expires_at
。现在,我假设如果订阅存在并且商店的至少一个订阅 expires_at 日期大于现在()。
它是整个查询的条件之一。这是代码:
$shops = Shop::when($subscription, function($query, $subscription) {
$query->doesntHave('subscriptions')->orWhereHas('subscriptions', function($q) use ($subscription, $query) {
$query->where('expires_at', '<', now());
});
});
它没有按预期工作,因为如果商店有三个相关订阅并且其中至少一个已过期 – 它假定商店没有活动订阅(即使它有)。
我需要在内部或 whereHas 实现一些嵌套函数,我想,按 expires_at desc 排序,然后限制为一个,然后才传递 where expires_at 子句,但是我已经不知道如何。
而且我宁愿坚持使用 Eloquent Query Builder 而不是 DB facade 或原始 sql。
基本上,这里没有回答的是同一个问题:
https://laracasts.com/discuss/channels/eloquent/latest-record-from-relationship-in-wherehas?page=1
试试这个:
$shops = Shop::doesntHave('subscriptions')->orWhereHas('subscriptions', function ($query) {
$query->whereDate('expires_at', '<', now());
})->get();
试试这个:
$shops = Shop::WhereHas('subscriptions')->withCount('subscriptions as
active_subscriptions_count' => function ($query) {
$query->where('expires_at', '<', now());
}])->having('active_subscriptions_count', '>=', 3)->get();
好的,所以在原始 sql 中尝试了一些之后我想通了:
$query->select('shops.*')
->leftJoin('subscriptions', 'shops.id', 'subscriptions.shop_id')
->whereNull('subscriptions.id')
->orWhere('subscriptions.expires_at', '<', now())
->where('subscriptions.id', function($q) {
$q->select('id')
->from('subscriptions')
->whereColumn('shop_id', 'shops.id')
->latest('expires_at')
->limit(1);
});
它不仅比 where exists 子句更快,而且还提供了我需要的东西——仅考虑给定商店的 "highest" 订阅。
我正在为我的应用构建搜索功能。为了简化事情: 有两个表:商店和订阅
每个店铺可以有多个订阅记录,订阅有字段expires_at
。现在,我假设如果订阅存在并且商店的至少一个订阅 expires_at 日期大于现在()。
它是整个查询的条件之一。这是代码:
$shops = Shop::when($subscription, function($query, $subscription) {
$query->doesntHave('subscriptions')->orWhereHas('subscriptions', function($q) use ($subscription, $query) {
$query->where('expires_at', '<', now());
});
});
它没有按预期工作,因为如果商店有三个相关订阅并且其中至少一个已过期 – 它假定商店没有活动订阅(即使它有)。
我需要在内部或 whereHas 实现一些嵌套函数,我想,按 expires_at desc 排序,然后限制为一个,然后才传递 where expires_at 子句,但是我已经不知道如何。
而且我宁愿坚持使用 Eloquent Query Builder 而不是 DB facade 或原始 sql。
基本上,这里没有回答的是同一个问题: https://laracasts.com/discuss/channels/eloquent/latest-record-from-relationship-in-wherehas?page=1
试试这个:
$shops = Shop::doesntHave('subscriptions')->orWhereHas('subscriptions', function ($query) {
$query->whereDate('expires_at', '<', now());
})->get();
试试这个:
$shops = Shop::WhereHas('subscriptions')->withCount('subscriptions as
active_subscriptions_count' => function ($query) {
$query->where('expires_at', '<', now());
}])->having('active_subscriptions_count', '>=', 3)->get();
好的,所以在原始 sql 中尝试了一些之后我想通了:
$query->select('shops.*')
->leftJoin('subscriptions', 'shops.id', 'subscriptions.shop_id')
->whereNull('subscriptions.id')
->orWhere('subscriptions.expires_at', '<', now())
->where('subscriptions.id', function($q) {
$q->select('id')
->from('subscriptions')
->whereColumn('shop_id', 'shops.id')
->latest('expires_at')
->limit(1);
});
它不仅比 where exists 子句更快,而且还提供了我需要的东西——仅考虑给定商店的 "highest" 订阅。