Laravel雄辩的选择数据

时间:2018-10-03 15:44:33

标签: database laravel eloquent

我想构建一个雄辩的查询,从而生成以下输出:

SELECT * FROM `banners` WHERE (`channel` = "en-us" OR `channel` IS NULL) AND (`language` = "en" OR `language`IS NULL) AND (`country` = 'us' OR `country` IS NULL) AND `category_id` = "3954" AND `valid_from` <= "2018-10-03 13:20:52" AND `valid_to` >= "2018-10-03 13:20:52" OR `valid_to` IS NULL

我在“ or”和“ and”条件下苦苦挣扎。

这应该表示有效_来源,有效_目的地,频道,语言必须具有值,但在某些情况下,“频道”和“语言”可以为空。

请帮助我。预先感谢!

2 个答案:

答案 0 :(得分:0)

这不是您发布的查询的确切输出,因为我在查询的右括号中看到一些语法错误。因此我无法完全理解您的查询。

但是,由于您已经指出您正在努力了解如何在and中使用orquery builder,所以我认为这可能会有所帮助。

DB::table('banners')
    ->where([                                         //     -|
        ['valid_from', '<=', '2018-10-03 13:20:52'],  // AND  |
        ['valid_to', '>=', '2018-10-03 13:20:52'],    // AND  |
        ['channel', 'en-us'],                         // AND  | OR
        ['language', 'en']                            // AND  |
    ])->orWhere([                                     //     _|____
        ['valid_from', '<=', '2018-10-03 13:20:52'],  // AND  | OR
        ['valid_to', null]                            // AND _|____
    ])->orWhereNull('channel')                        //     _| OR
    ->orWhereNull('language')                         //     _| OR
    ->get();

祝你好运

答案 1 :(得分:0)

我假设您的口才是Banner

public function valid_banner() {
        $data = $this
            ->where(function ($query) {
                $query
                    ->where('valid_from', '<=', '2018-10-03 13:20:52')
                    ->where('valid_to', '>=', '2018-10-03 13:20:52')
                    ->where('channel', 'en-us')
                    ->where('language', 'en');
            })
            ->orWhere(fucntion($query) {
                $query
                    ->where(function($q) {
                        $q
                            ->where('valid_from', '<=', '2018-10-03 13:20:52')
                            ->whereNull('valid_to');
                    })
                    // i think you can use this (choose one of below)
                    ->orWhereNull('channel')
                    // use this if orWhereNull is not exists
                    ->orWhereRaw("channel IS NULL")

                    // i think you can use this (choose one of below)
                    ->orWhereNull('language')
                    // use this if orWhereNull is not exists
                    ->orWhereRaw("language IS NULL");
            })
            ->where('category_id', 3954)
            // you can skip this condition if you using SoftDeletes
            // read this https://laravel.com/docs/5.6/eloquent#soft-deleting
            ->whereNull($this->getTable(). '.deleted_at')

        ;

        return $data;
}

尚未测试。但希望您能明白这一点。