如何从 laravel 5.1 数据库 table 的 created_at 属性中 select 年和月?
How to select year and month from the created_at attributes of database table in laravel 5.1?
我的问题是我只想从数据库 table 的 created_at
属性中获取数据,仅按年份和月份计算。我试过的代码是:
$post= Mjblog::select(DB::raw('YEAR(created_at) year, MONTH(created_at) month'));
$posts_by_y_m = $post->where('created_at',$post)->get();
查询构建器中有可用的日期助手:
$post = Mjblog::whereYear('created_at', '=', $year)
->whereMonth('created_at', '=', $month)
->get();
如果您想从 Mjblog
的单个实例中获取年份和月份,您可以像这样访问它们:
$year = $post->created_at->year;
$month = $post->created_at->month;
详细了解 Carbon\Carbon
getters documentation。
绩效评估
尽管接受的答案可能会解决 OP 问题,但那是 NOT OPTIMAL解决方案 在数据库性能方面。
因为当应用whereYear()
或whereMonth()
helper查询记录时,它使得查询Non-SARGable. This means if the compared column created_at
is indexed in database then this index is ignored while searching the data. See What makes a SQL statement sargable?
考虑以下表达式
$posts = Mjblog::whereYear('created_at', '=', $year)
->whereMonth('created_at', '=', $month)
->get();
结果查询将像
select *
from mjblog
where year(`created_at`) = :year
and month(`created_at`) = :month
上面的查询可以清楚地看出是不可搜索的,因为 year()
和 month()
函数应用于 created_at
产生非索引值。
要使其成为 SARGable 表达式,最好在比较索引列时定义值的 exact/range。与 OP 一样,范围可以从月份和年份值导出为
$year = 2000;
$month = 2;
$date = \Carbon\Carbon::parse($year."-".$month."-01"); // universal truth month's first day is 1
$start = $date->startOfMonth()->format('Y-m-d H:i:s'); // 2000-02-01 00:00:00
$end = $date->endOfMonth()->format('Y-m-d H:i:s'); // 2000-02-29 23:59:59
现在SARGable表达式可以写成
select *
from mjblog
where created_at between :start and :end
或者
select *
from mjblog
where created_at >= :start
and created_at <= :end
在查询构建器中它可以表示为
$posts = Mjblog::whereBetween('created_at', [$start, $end])
->get();
或者
$posts = Mjblog::where('created_at', '>=', $start)
->where('created_at', '<=', $end)
->get();
缺点的有用文章
我的问题是我只想从数据库 table 的 created_at
属性中获取数据,仅按年份和月份计算。我试过的代码是:
$post= Mjblog::select(DB::raw('YEAR(created_at) year, MONTH(created_at) month'));
$posts_by_y_m = $post->where('created_at',$post)->get();
查询构建器中有可用的日期助手:
$post = Mjblog::whereYear('created_at', '=', $year)
->whereMonth('created_at', '=', $month)
->get();
如果您想从 Mjblog
的单个实例中获取年份和月份,您可以像这样访问它们:
$year = $post->created_at->year;
$month = $post->created_at->month;
详细了解 Carbon\Carbon
getters documentation。
绩效评估
尽管接受的答案可能会解决 OP 问题,但那是 NOT OPTIMAL解决方案 在数据库性能方面。
因为当应用whereYear()
或whereMonth()
helper查询记录时,它使得查询Non-SARGable. This means if the compared column created_at
is indexed in database then this index is ignored while searching the data. See What makes a SQL statement sargable?
考虑以下表达式
$posts = Mjblog::whereYear('created_at', '=', $year)
->whereMonth('created_at', '=', $month)
->get();
结果查询将像
select *
from mjblog
where year(`created_at`) = :year
and month(`created_at`) = :month
上面的查询可以清楚地看出是不可搜索的,因为 year()
和 month()
函数应用于 created_at
产生非索引值。
要使其成为 SARGable 表达式,最好在比较索引列时定义值的 exact/range。与 OP 一样,范围可以从月份和年份值导出为
$year = 2000;
$month = 2;
$date = \Carbon\Carbon::parse($year."-".$month."-01"); // universal truth month's first day is 1
$start = $date->startOfMonth()->format('Y-m-d H:i:s'); // 2000-02-01 00:00:00
$end = $date->endOfMonth()->format('Y-m-d H:i:s'); // 2000-02-29 23:59:59
现在SARGable表达式可以写成
select *
from mjblog
where created_at between :start and :end
或者
select *
from mjblog
where created_at >= :start
and created_at <= :end
在查询构建器中它可以表示为
$posts = Mjblog::whereBetween('created_at', [$start, $end])
->get();
或者
$posts = Mjblog::where('created_at', '>=', $start)
->where('created_at', '<=', $end)
->get();
缺点的有用文章