首页 > 解决方案 > 根据所选选项过滤查询

问题描述

我正在尝试在我的应用程序中创建过滤器搜索,其中您具有以下模型:

一位访客可以有许多属性响应用于保存详细信息,例如姓名、姓氏、语言环境等等

我想要完成的事情

在此处输入图像描述

如图所示,我想检索具有 Attributeresponse 的访问者,列名称 = "name" 并且它的值 = "hector22" AND 同时列 name = "locale" 和它的值 = "es"

换句话说,检索名称 = hector22 和语言环境 = es 的访问者。

这就是我目前在 SQL 中所拥有的:

select
  *
from
  `visitors`
where
  `bot_id` = '1255'
  and exists (
    select
      *
    from
      `attributeresponses`
    where
      `visitors`.`id` = `attributeresponses`.`visitor_id`
      and (
        `attributeresponses`.`attribute_name` = 'name'
        and `attributeresponses`.`value` = 'hector22'
      )
      and (
        `attributeresponses`.`attribute_name` = 'locale'
        and `attributeresponses`.`value` = 'es'
      )
  )
order by
  `visitors`.`id` desc
limit
  10 offset 0

这是在雄辩的

            // retrieve visitors related to filters
            $visitors = Visitor::where('bot_id', $data['bot_id'] )
            // ->with(['properties' => function($topQuery) use ($data, $filters) {
            ->whereHas('properties', function($query) use ($filters, $data) {
                
            foreach( $filters as $key => $filter ){


                    $query->where(function($q) use ($filter) {
                                                        
                            $q->where('attributeresponses.attribute_name', $filter['property'] );

                            if($filter['operator'] == 1){
                                // IS equal
                                $q->where('attributeresponses.value', $filter['value'] );
                            }else if($filter['operator'] == 2){
                                // IS NOT equal
                                $q->where('attributeresponses.value', '!=', $filter['value']);                        
                            }else if($filter['operator'] == 3 && (is_numeric($filter['value'])) ){
                                // IS greater than
                                $q->where('attributeresponses.value', '>', $filter['value']);                        
                            }else if($filter['operator'] == 4 && (is_numeric($filter['value'])) ){
                                // IS less than
                                $q->where('attributeresponses.value', '<', $data['filters']['value']);                                                
                            }    
                        });


               


            }     
            })                        


            ->limit( 10 )
            ->offset( ( $data['paginate'] == 0 ? 0 : $data['paginate'] *10) )
            ->orderBy( 'visitors.id', 'desc' )
            ->get();     

我仍在为此苦苦挣扎,因为它没有带来任何记录,而且我确实有一个访问者在 Attributeresponse 下有一条记录,名称 = "name" 和 value = "hector22",而这个相同的访问者有另一个 Attributeresponse,名称 = "locale " 和值 = "es"

如果我不能说清楚我很抱歉

标签: mysqllaravel

解决方案


未经测试(显然),但只是需要考虑的事情

select v.*
  from visitors v
  join attributeresponses r
    on r.visitor_id = v.id
where v.bot_id = 1255
   and (r.attribute_name,r.value) IN (('name','hector22'),('locale','es'))
Group 
    by v.id
having Count(distinct (r.attribute_name,r.value)) = 2
 order 
     by v.id desc
limit 10 
offset 0

推荐阅读