Php 基于独占值获取结果:mysql&;拉维尔
由于我的词汇量不足,我不确定我的问题的标题是否正确,但我正在尽可能详细地解释我的需要。谢谢你通过 我有一张桌子,专门用来存放活动的成员。下图所示Php 基于独占值获取结果:mysql&;拉维尔,php,mysql,laravel,Php,Mysql,Laravel,由于我的词汇量不足,我不确定我的问题的标题是否正确,但我正在尽可能详细地解释我的需要。谢谢你通过 我有一张桌子,专门用来存放活动的成员。下图所示 event_id | user_id ---------|--------------------- 1 | 23 1 | 32 3 | 23 3 | 32 3 | 67 我想根据提供的user\u id的值检索event\u id,但我只想显示专门为用户提供的event\u id
event_id | user_id
---------|---------------------
1 | 23
1 | 32
3 | 23
3 | 32
3 | 67
我想根据提供的user\u id
的值检索event\u id
,但我只想显示专门为用户提供的event\u id
例如,根据表的上图,如果我只给用户值=(23,32),那么我应该只检索事件1,而不是同时检索1和3,即使事件3也有上述用户。我正在尝试检索仅对给定用户独占的事件
以下是我的laravel实现:
DB::table('events_users')->whereIn('user_id', [23, 32])
->get();
这将获取具有以上用户的所有事件,但根据上图,我想要id为1的唯一事件。我当前的解决方案是在获取后编写另一层代码,将查询结果中每个事件的用户数与所需的计数进行匹配。例如,如果我只搜索2个用户独占事件,那么我将根据事件中的总用户数从结果中筛选出事件。对不起,我的词汇量很弱,但我正在尽力解释
有没有一种方法可以通过单个查询实现我想要的功能?一种SQL方法是使用基于条件聚合的过滤。我们使用
groupby
对事件进行聚合,然后使用HAVING
子句过滤掉行:
SELECT event_id
FROM events_users
GROUP BY event_id
HAVING
SUM(user_id = 23) -- event exists for user = 23
AND
SUM(user_id = 32) -- event exists for user = 32
AND
NOT SUM(user_id NOT IN (23,32)) -- no other row exists other than user 23 and 32
我认为以下解决方案也可以:
SELECT DISTINCT event_id FROM events_users GROUP BY event_id
HAVING GROUP_CONCAT(DISTINCT user_id ORDER BY user_id asc SEPARATOR ',')="23,32"
您可以在查询之前对user_id数组进行排序并将其转换为字符串
Laravel查询生成器方法:
$user_id_str=implode(",",[23,32]);
DB::table('events_users')
->selectRaw("distinct event_id")
->groupBy('event_id')
->havingRaw("GROUP_CONCAT(DISTINCT user_id ORDER BY user_id asc SEPARATOR ',')='$user_id_str'")->get();
编辑:此解决方案不适用于具有相同类型独占成员的多个事件的场景。这是不正确的解决方案。我道歉。 来自Phil的解决方案有效,因此我将其标记为解决方案。 我找到了对我有效的解决方案。如果你认为有缺陷,请让我知道
DB::table('events_users')
->whereIn('user_id', [23, 32])
->havingRaw('count(user_id) = ?', [2])
->get();
这为我提供了只有用户23和32的独占事件,没有其他成员。我假设给定的用户数和用户数是互斥的,因为事件中不会有重复的用户条目。如果在任何情况下都失败,请告诉我。您想要纯原始SQL查询吗?或者,基于Laravel的解决方案?基于Laravel的。但若你们有原始查询解决方案,那个么我想我可以自己尝试将原始查询实现到laravel解决方案中。谢谢。据我所知,您想知道ID为23和32的用户之间的常见(相同)事件是什么。我说的对吗?不,我想要的活动只有23和32名成员。因为事件1和3都由两个用户共享,但在事件3中也有其他成员在场,因此不是23和32的独家事件。是的,这是有效的。上面的代码应该使您的集合不为null。如果未找到匹配项,则它应获取空集合,但afaik不能为null。是的,它获取了空集合。但是你想得到第一件事,对吗?是的。对我来说,这是回归事件1。我的项目正在进行中。能否确保在表中,事件1只有2个您正在搜索的成员?在上面的代码中,我正在搜索(23和32),并确保事件只有2个成员。是的。我在本地环境中复制了您的数据。我的建议也适用于我当地的环境。它起作用了。我用表中的所有真实数据进行了测试,并进行了各种组合。这也是我的json响应。{“message”:“Event exists.”,“data”:{“Event_id”:1,“created_at”:“2019-09-21 12:00:14”,“updated_at”:“2019-09-21 12:00:14”}对于输入顺序为非顺序的场景,您是否存在问题?如果我没有事先订购输入。例如,如果我用(32,23)而不是(23,32)搜索,我不会得到结果。我认为这是因为我们在最后比较字符串,这些字符串是按给定顺序连接的输入值版本。现在,我要确保在将输入发送到查询之前,先对输入进行asc或desc排序。所以它在那里起作用。但我只是好奇。对于任何类型的订单,是否有替代方案?。谢谢