对于根据时间段来查询数据,数据库怎样设计好?

因为数据量的问题,需要将数据进行 周统计、月统计、年统计,这是没问题的,可是真正的问题来的,当用户不按照 “2017-11-01 , 2017-11-30” 这种整月,而是这种“2017-10-13 , 2017-11-13” 形式去查询的时候,我应该怎样去拿数据呢,或者说 我怎样去建一个数据表呢? 先谢过 各大神了。。

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 27

给个参考:

User::whereRaw('left(`created_at`, 10)>="2017-10-13"')->get()
6年前 评论

@施国鹏 谢谢您的指点,不明白的是您为什么要使用left()函数,不知道是否用 between 会更好一些呢

6年前 评论

有更好的方法,我看了作者的视频的,但是忘了怎么写的,我晚点告诉你。

6年前 评论
leo

如果数据量大,实时统计是很难的,通常是每天凌晨去跑一下数据存起来,然后查的时候就直接查结果就行了

6年前 评论

@欧阳逸 恩恩,好的,谢谢啦

6年前 评论

@leo 对于那种不正常的 就像 (2017-10-13 , 2017-11-13)这种时间段的筛选数据,对数据怎么去做统计比较好呢

6年前 评论

2017-11-16 14:24:37 是 datetime 类型,2017-11-16 是 date 类型,这两个类型指的是 MySQL 数据类型。这两个类型中,均可以使用 > 和 < 进行筛选,即:Article::where('created_at', '>', '2017-11-16 14:26:33')->get() 甚至直接拿 date 类型的数据去 datetime 字段筛选,都是支持的。

6年前 评论

@johnlui 恩 了解,现在问题是,数据量大,用这种where('created_at', '>', '2017-11-16 14:26:33')这种查询的效率就会很低,所以有没有 可以统计这种没有规律的时间段内数据的 方法。

6年前 评论

@Wanzj 数据量有多大,效率有多低?我帮你对症下药

6年前 评论

@johnlui 恩恩,谢谢了, 我有个商品数据表,存的是各大商城每天商品的销量的,现在每天会向数据表插两百条商品的销量,现在差不多有八十万条数据。我需要做的是根据用户选择的时间段,去统计这段时间内的数据,然后合并相同品牌的数据且将销量相加,其实我现在就是用的您说的那种方式,但是我想偷懒一下,做一个统计表,这样就可以将一周的7条数据变成一条数据,一个月的30条数据也变成一条数据,这样会节省不少时间, 但是我遇到了一个问题:当用户选了 2017-01-25 - 2017-11-14这样一段时间的时候,我该怎么办呢 @johnlui 非常感谢您上面给的提示,谢谢

6年前 评论

这种非确定时间的统计只能实时来做,建议从优化数据库性能方向着手。

6年前 评论

@johnlui 好的大哥,让我受益匪浅,谢谢啦

6年前 评论
leo

@Wanzj 还有一种办法,告诉产品经理这个不好做,让他找妥协的方案

6年前 评论

@leo 哈哈,产品找来了 某某数据分析平台,说,人家的这个功能实现了,我也是很无语。。

6年前 评论

查询最近7天,设置要查询的天数就行了

$days = Input::get('days', 7);

$range = \Carbon\Carbon::now()->subDays($days);

$stats = User::where('created_at', '>=', $range)
    ->groupBy('date')
    ->orderBy('date', 'DESC')
    ->remember(1440)
    ->get([
        DB::raw('Date(created_at) as date'),
        DB::raw('COUNT(*) as value')
    ])
    ->toJSON();
6年前 评论

@Wanzj 看我的答案,直接用mysql的date函数,结合Carbon,爽爆了。

$days = Input::get('days', 7);

$range = \Carbon\Carbon::now()->subDays($days);

$stats = User::where('created_at', '>=', $range)
    ->groupBy('date')
    ->orderBy('date', 'DESC')
    ->remember(1440)
    ->get([
        DB::raw('Date(created_at) as date'),
        DB::raw('COUNT(*) as value')
    ])
    ->toJSON();
6年前 评论

@欧阳逸 多谢多谢,有个问题,你查询中的 ->remember(1440) 是一个什么样的用法,我没有用过,是缓存么?

6年前 评论

@Wanzj 对的,但是有的好像不支持,你把那一行去掉就行了。我现在就是用这个搞的。统计就很简单了

6年前 评论

@Wanzj User::whereBetween('created_at', [$start, $end]);用这个统计区间

6年前 评论

@欧阳逸

return $this->where('category_id',$category)
                      ->whereBetween('sort_time',[$st,$et])
                      ->where('device_type',1)
                      ->select(\DB::raw('sum(amount) as y,device as x'))
                      ->groupby('x')
                      ->get();

我现在是所有的数据都是用的区间查的,暂时没有做统计表

6年前 评论

@cainiao9980 那麻烦您指出 “弱智” 之处,不足之处我去修改

6年前 评论
Summer

@Wanzj 该用户已被禁言,大家下次遇到此类回答,不论他多有理,都 @ 我处理。

6年前 评论

@Summer 好的老大,:thumbsup: :thumbsup:

6年前 评论

进行表分区,如果表数据字段非常多,已经非常大了,可以建个新表,新表分区,就保存需要统计的字段。进行任务定时,往新表,新增数据

5年前 评论
TigerLin

@欧阳逸 你能告诉你 Input::get() 这是个什么用法吗

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!