【问题标题】:laravel - query builder cross join sub querylaravel - 查询生成器交叉连接子查询
【发布时间】:2020-03-12 10:30:23
【问题描述】:

我做了一个sql查询,想用构建器在laravel中构建它,

我在子查询上使用了交叉连接来获取两个日期之间的所有行数,如果匹配,它将填充数据,否则用 null 填充。

SQL:

select 
    username,
    date_gen as date,
    skill_exp.*
from users cross join (
SELECT
    date_gen
from (
    select DATE_ADD(curdate() - INTERVAL 10 DAY, INTERVAL (@i:=@i+1)-1 DAY) as `date_gen`
    from information_schema.columns,(SELECT @i:=0) gen_sub 
    where DATE_ADD(curdate() - INTERVAL 10 DAY,INTERVAL @i DAY) BETWEEN curdate() - INTERVAL 10 DAY AND curdate()
    ) date_generator
) date_gen
left join skill_exp on users.id = skill_exp.user_id and date_gen.date_gen = skill_exp.date
where username = 'thebloodeyes'

我怎样才能在 laravel 中制作子部分,以便我可以在左侧使用它加入到 Skill_exp 中

子查询部分:

SELECT
    date_gen
from (
    select DATE_ADD(curdate() - INTERVAL 10 DAY, INTERVAL (@i:=@i+1)-1 DAY) as `date_gen`
    from information_schema.columns,(SELECT @i:=0) gen_sub 
    where DATE_ADD(curdate() - INTERVAL 10 DAY,INTERVAL @i DAY) BETWEEN curdate() - INTERVAL 10 DAY AND curdate()
) date_generator;

结果子查询: 结果总查询:

【问题讨论】:

  • “我做了一个 sql 查询,想用构建器在 laravel 中构建它,” 解决这个问题的简单方法是在 MySQL 中创建一个 VIEW 并查询/在 laravel 中使用它而不是 .. 但这很可能无法在大型到非常大的表上很好地扩展,因为 GROUP BY 会强制 MySQL 处理该 VIEW 以作为 internal temporary table 而不是 merging 运行。
  • .. 还有这个 GROUP BY 接缝在这里被滥用以“取消重复”那些生成的日期......我从那个 SQL 部分理解的重复日期永远不会发生......所以GROUP BY这里几乎不需要部分.. 另外我会将其表述为this 而不是使用information_schema.columns 然后您可以更好地控制数字生成器生成和加入的最大记录数..
  • ... 如果information_schema.columns 缓存,information_schema.columns 也可以触发一些(随机)磁盘 I/O(每个表延迟 4 ms - 10 ms)也打开所有现有表的元文件不知何故变得无效,需要刷新..
  • “我做了一个sql查询,想用builder在laravel中构建,” 回到主题:应该在Database: Query Builder laraval manual你需要查看JOIN 部分中的 "Advanced Join Clauses/Sub-Query Joins" 使那些派生(子查询)表成为可能。其他DATE_ADD(curdate() - INTERVAL 10 DAY, INTERVAL (@i:=@i+1) 语法例如可以是Raw Expression
  • 感谢您提供的信息,我正试图弄清楚这一切是如何运作的。查看您发送的 SQL 是如何工作的。并且通过联接,它希望我在 table.something = other.something 上做一个,我该如何解决我无法找到的问题

标签: mysql laravel


【解决方案1】:

我忽略了数据库将处理丢失的日期并将其移至 php.ini 文件。 让我知道是否有一些错误或者在数据库中处理这个会更可取

执行时间:0.035382032394409ms~
向api请求时间:105ms~

开始日期:2013-06-01 结束日期:2025-07-01 数据库日期总计:1, 2018-10-21

        $user = User::with(['exp' => function ($query) {
            $query->whereDate('date', '>=', '2018-10-21');
        }])
            ->where('username', '=', $id)
            ->firstOrFail();


        return Helper::addMissingDates("2013-06-01", "2025-07-01", $user->exp);

addMissingDates 函数:

    public static function addMissingDates($dateStart, $dateEnd, $expTables) {
        $newExpTable = [];
        $begin = new DateTime( $dateStart );
        $end = new DateTime($dateEnd);
        $end = $end->modify( '+1 day' );

        $interval = new DateInterval('P1D');
        $daterange = new DatePeriod($begin, $interval ,$end);

        foreach($daterange as $date) {
            foreach ($expTables as $expTable) {
                if($date->format("Y-m-d") === $expTable->date) {
                    $newExpTable[] = $expTable;
                    continue 2;
                }
            }
            $exp = new \stdClass();
            $exp->found = false;
            $exp->date = $date->format("Y-m-d");
            $newExpTable[] = $exp;
        }


        return $newExpTable;
    }

【讨论】:

    猜你喜欢
    • 2011-08-15
    • 1970-01-01
    • 2022-01-20
    • 2012-12-31
    • 2014-05-13
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 2013-08-07
    相关资源
    最近更新 更多