【问题标题】:Passing MySQL functions to Eloquent ORM query将 MySQL 函数传递给 Eloquent ORM 查询
【发布时间】:2012-12-25 08:02:08
【问题描述】:

我正在尝试在 Eloquent ORM 中执行以下查询,但似乎无法执行 MySQL 函数 -

$post = Post::where('slug', '=', $slug)->where('YEAR(created_at)', '=', $year)->first();

我得到的异常如下 - 留言:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'YEAR(created_at)' in 'where clause'

SQL: SELECT * FROM `posts` WHERE `slug` = ? AND `YEAR(created_at)` = ? LIMIT 1

Bindings: array (
  0 => 'placeholder',
  1 => 2013,
)

所以,基本上,它将YEAR() MySQL 函数封装为一列。有没有办法在不使用原始查询的情况下做到这一点?

【问题讨论】:

  • 你想在 YEAR(created_at) 之前实现什么? ''''$year'''' 通常的值是多少?
  • $year 就是这样 - 带有年份的变量,例如 2013。created_at 是 MySQL 时间戳列,例如,YEAR(created_at) 将返回 2013。

标签: php database laravel eloquent


【解决方案1】:

为了防止 Eloquent ORM 用撇号包装第一个变量,您可以使用 DB:raw 函数,例如:

$post = Post::where('slug', '=', $slug)
        ->where(DB::raw('YEAR(created_at)'), '=', $year)
        ->first();

你会得到查询:

SELECT * FROM `posts` WHERE `slug` = ? AND YEAR(created_at) = ? LIMIT 1

【讨论】:

  • 这个 3 年前的帖子今天救了我的命。非常感谢您,先生:-)
  • 这篇文章在使用 mariadb 动态列保存数据时帮助我,谢谢先生!
【解决方案2】:

无论如何,您可能不想在 WHERE 子句中使用 YEAR() 函数。这将阻止您在 created_at 列上使用任何索引。我建议你改用LIKE:

$post = Post::where('slug', '=', $slug)->where('created_at', 'LIKE', $year . '%')->first();

如果您需要在查询中使用不受支持的 MySQL 函数,您也可以只使用原始 SQL 查询(使用 query() 方法)。

【讨论】:

  • 我的目标是有一个沿着这些行的 URL = example.com/blog/2013/01/01/blog-post,所以我需要一些方法来剖析 created_at 列来过滤年、月和日。
  • 好的,但这与问题有什么关系?您的查询似乎只是在寻找第一个带有特定 slug 和一年的帖子并返回第一个。如果您需要按年和月排序,您只需将类似条件更改为$year . '-' . $month,如果您有日期值,您也可以添加它(或者在 DB 字段的那个点使用=日期字段)。只在月或日做 WHERE 可能没有意义,所以只需从左到右构建日期条件,允许您在字段上使用索引(您确实有索引吗?)
  • 我正在尝试减少使用重复 slug 拉帖子的可能性,这就是这里的目标。
  • @NightMICU 为什么不只在slug 上放置一个唯一索引并使用该值进行查找?还是将整个 URI 视为一个 slug(再次使用唯一索引)?
【解决方案3】:

你有两种方法可以做到这一点,这取决于你的 laravel 版本

首先使用Raw方法传递函数,如下例

$post = Post::where('slug', $slug)
     ->where(DB::raw('YEAR(created_at)'), $year)
     ->first();

ِ您也可以在 (select,group,order) 方法中使用它,以获取有关 Raw Laravel Docs 的更多信息,它从 v 4.2 开始

第二次使用whereYear方法

$post = Post::where('slug', $slug)
      ->whereYear('created_at', $year)
      ->first();

此方法从 V 5.3 开始以获取更多信息Read Where section 您将找到所有日期方法(whereDate / whereMonth / whereDay / whereYear)

【讨论】:

    【解决方案4】:

    我使用 Laravel 5.3

    $post = Post::where('slug', '=', $slug)->whereYear('created_at', '=', $year)->first();
    

    这家伙帮了我>>https://stackoverflow.com/a/32843415/7752468

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 2019-03-15
    • 2016-07-06
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 2018-10-31
    相关资源
    最近更新 更多