计算复杂查询

时间:2014-02-04 16:21:08

标签: php mysql laravel-4

我将用一个例子解释我的问题:

的: 地点 - 评论 - activities_comment - 活动

用户可以评论某个地点,并选择在该地方可以进行的活动类型。 活动包括:跑步,游泳,散步和攀爬。

所以一些用户会投票超过1个活动,所以我不能把它放在同一个表COMMENT中,我需要创建一个枢轴表ACTIVITIES_COMMENT,问题就在这里,我是能够显示在每个地方选择的活动的所有评论..

但是现在我想要计算活动的数量,并按照最常选择的活动对其进行排序,以便用户在每个地方的评论中选择较少。 我怎样才能做到这一点??

我能做的最好的事情是:

$place = Place::with('city','comments')
            ->where('id',$placeId)->first();


$place->activities = Activity::join('activities_comment', 'activity.id', '=', 'activities_comment.activity_id')
            ->join('comment', 'comment.id', '=', 'activities_comment.comment_id')
            ->select('comment.id','activities_comment.activity_id',
                DB::raw('(SELECT count(activities_comment.activity_id) FROM activities_comment WHERE activities_comment.activity_id = 1) as run'),
                DB::raw('(SELECT count(activities_comment.activity_id) FROM activities_comment WHERE activities_comment.activity_id = 2) as swim'),
                DB::raw('(SELECT count(activities_comment.activity_id) FROM activities_comment WHERE activities_comment.activity_id = 3) as walk'),
                DB::raw('(SELECT count(activities_comment.activity_id) FROM activities_comment WHERE activities_comment.activity_id = 4) as climb'),
                )
            ->where('comment.place_id',$place->id)
            ->get();

问题在于此查询会计算最多选定的活动,但在所有地方,我只想在每个地方计算。


修改

示例行:

地方表格:

id | name
----------
1  | Alaska
2  | Peru
3  | Argentina

评论表:

id | user_id | place_id | text
------------------------------------
1  | 1       | 1        | some text
2  | 3       | 1        | some text
3  | 2       | 2        | some text

活动表:

id | name 
----------
1  | run
2  | swim
3  | walk
4  | climb

activity_comment 表格:

id | comment_id | activity_id
------------------------------
1  | 1          | 1        
2  | 1          | 2        
3  | 2          | 2       
4  | 3          | 2

当我进入阿拉斯加的评论时,我希望看到用户在那里选择活动的时间,对于阿拉斯加州它会显示:

run: 1 time
swim: 2 times
walk: 0 times
climb: 0 times

如果我去秘鲁评论:

run: 0 times
swim: 1 time
walk: 0 times
climb: 0 times

提前谢谢。

1 个答案:

答案 0 :(得分:0)

首先,通过连接将表格全部链接起来,显示每个表格如何通过各自的键与下一个表格相关联。然后,它只是每个名称(城市/位置)和活动名称的问题,并获得按相应位置和活动分组的计数。 order by子句将首先放置所有相同的位置,然后在每个位置内将最高计数活动设为次要...如果有任何相同的计数,则名称将按字母顺序排列

SELECT
      p.name,
      a.name as Activity,
      COUNT(*) as NumComments
   from
      place p
         join comment c
            ON p.id = c.place_id
            join activity_comment ac
               ON c.id = ac.comment_id
               join activity a
                  ON ac.activity_id = a.id
   group by
      p.name,
      a.name
   order by
      p.name,
      COUNT(*) desc,
      a.name

现在,您只需要插入WHERE子句(在分组之前)插入您可能感兴趣的任何位置或活动。