Laravel / SQL按流行度/趋势排序

时间:2017-06-19 01:47:24

标签: php mysql sql laravel

我有一个包含图片的网站,图片可以包含标签。许多图像也可以具有相同的标记。所以2张图片可以标记为“绘画”。

我有一个images表,一个tags表和一个images_tag数据透视表。

images_tag表格包含以下列:idimages_idtag_idcreated_at

我想要的是能够在过去72小时内找到哪些标签趋势。

这意味着我希望获得一个查询,其中包含过去72小时内使用的所有标记

$trendingTags = ImagesTag::where('created_at', '>=', Carbon::now()->subHours(72))

并且比如说最常用的3个标签。所以在这种情况下

$trendingTags = ImagesTag::where('created_at', '>=', Carbon::now()->subHours(72))
->orderBy('tag_id most frequently used', 'desc')
->take(3);

我怎样才能做到这一点?

修改

在回应fubar的回答时,我尝试了以下内容:

控制器:

$trendingTags = Tag::selectRaw('tags.*, COUNT(image_tag.id) AS count')
->join('image_tag', 'tags.id', '=', 'image_tag.tag_id')
->where('created_at', '>=', Carbon::now()->subHours(72))
->orderBy('count', 'desc')
->take(3);

return view('home')
>with('trendingTags', $trendingTags)

这给了我错误:

  

SQLSTATE [42S02]:找不到基表或视图:1146表   'commendme.image_tag'不存在(SQL:选择count(*)作为聚合   来自tags的{​​{1}}内部加入image_tagtags =   idimage_tag其中tag_id> = 2017-06-16 02:44:02   按created_at desc limit 3)

所以我尝试切换代码来反映images_tag表(而不是image_tag,我猜这是fubar的一个错字),我又得到了一个错误:

  

SQLSTATE [42S22]:未找到列:1054未知列'count'   'order clause'(SQL:选择count(*)作为count内部的聚合   在tags上加入images_tagtags = idimages_tag其中   tag_id> = 2017-06-16 02:45:15按created_at desc限制排序3)   (视图:   C:\ XAMPP \ htdocs中\系列\称道-ME \ CommendMe \资源\视图\ home.blade.php)

编辑2:

尝试fubar上次编辑后的新错误:

  

SQLSTATE [42S22]:找不到列:1054未知列'image_count'   在'order clause'中(SQL:选择count(*)作为count内部的聚合   在tags上加入images_tagtags = idimages_tag其中   tag_id> = 2017-06-16 02:55:17分组created_attags按顺序排列   id desc limit 3)(查看:   C:\ XAMPP \ htdocs中\系列\称道-ME \ CommendMe \资源\视图\ home.blade.php)

1 个答案:

答案 0 :(得分:3)

我猜测你的解释是你真的想要Tag模型本身,而不是透视数据。

如果是,则需要将tags表加入image_tag表,然后计算imagestags表之间的数字关系。获得此值后,只需按顺序排序即可。

$trendingTags = Tag::selectRaw('tags.*, COUNT(images_tag.id) AS image_count')
    ->join('images_tag', 'tags.id', '=', 'images_tag.tag_id')
    ->where('images_tag.created_at', '>=', Carbon::now()->subHours(72))
    ->groupBy('tags.id')
    ->orderBy('image_count', 'desc')
    ->take(3)
    ->get();

修改

回应OP发布的错误。

我注意到我引用的连接表实际上称为images_tag,而不是image_tag。 OP,这是一个Laravel标准,在命名数据透视表时按字母顺序使用关系的单数名称。然而,我修改了我的答案。

我还注意到我错过了groupBy聚合器函数所需的重要SQL语句。

最后,我已将count重命名为image_count,以防MySQL将其视为保留字。

编辑#2

我刚刚在我的一个项目中对此进行了测试,并且按预期工作。

$categories = FaqCategory::selectRaw('faq_categories.*, COUNT(faq_faq_category.id) AS faq_count')
    ->join('faq_faq_category', 'faq_categories.id', '=', 'faq_faq_category.faq_category_id')
    ->groupBy('faq_categories.id')
    ->orderBy('faq_count', 'desc')
    ->take(3)
    ->get();