【问题标题】:Laravel/SQL sort by popularity/trendingLaravel/SQL 按流行度/趋势排序
【发布时间】:2017-06-19 01:47:24
【问题描述】:

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

我有一个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: select count(*) as aggregate 来自tags 内部连接image_tagtags.id = image_tag.tag_id 其中created_at >= 2017-06-16 02:44:02 订单 by count desc 限制 3)

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

SQLSTATE[42S22]:未找到列:1054 未知列“计数”在 'order 子句' (SQL: select count(*) as aggregate from tags inner 在tags.id 上加入images_tag = images_tag.tag_id created_at >= 2017-06-16 02:45:15 order by count desc limit 3) (看法: C:\xampp\htdocs\series\commend-me\CommendMe\resources\views\home.blade.php)

编辑 2:

尝试 fubar 的最后一次编辑后出现新错误:

SQLSTATE[42S22]:未找到列:1054 未知列 'image_count' 在“顺序子句”中(SQL:从tags 内部选择计数(*)作为聚合 在tags.id 上加入images_tag = images_tag.tag_id created_at >= 2017-06-16 02:55:17 group by tags.id order by image_count desc 限制 3) (查看: C:\xampp\htdocs\series\commend-me\CommendMe\resources\views\home.blade.php)

【问题讨论】:

  • 您收到错误 unknown column 'image_count',因为您忘记重命名别名,因此请在查询中更改:COUNT(images_tag.id) AS image_count

标签: php mysql sql laravel


【解决方案1】:

我从您的解释中猜测您实际上想要的是 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();

【讨论】:

  • 感谢您的回答。不幸的是,您的代码给了我一些错误。我已经编辑了主要帖子以显示这些错误。
  • 试过了。另一个错误。再次编辑主帖。
  • 我在Builder 的末尾添加了缺少的get() 调用,但除此之外,这对我有用。您可能希望使用特定的 Laravel、PHP 和 MySQL 版本更新您的问题。
  • 有效!非常感谢。我也在研究 withCount 方法是否会在这里有所帮助,但不管现在。
猜你喜欢
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 2020-02-05
  • 2021-12-11
  • 2011-11-15
  • 1970-01-01
  • 2013-05-08
  • 2013-11-18
相关资源
最近更新 更多