Laravel 是否可以在没有DB:Raw的情况下从多个表中进行选择?
关于Laravel的查询生成器的一些noob问题。 我正在尝试转换简单的SQL查询:Laravel 是否可以在没有DB:Raw的情况下从多个表中进行选择?,laravel,Laravel,关于Laravel的查询生成器的一些noob问题。 我正在尝试转换简单的SQL查询: SELECT s.name, e.name, m.name FROM sports as s, events as e, matches as m WHERE s.name = 'Football' 其中运动->事件->比赛具有1->n关系 Match有一个事件id外键 事件具有sport_id外键 体育是根 因此,上面使用s.name='Football'的select查询给出: +----------
SELECT s.name, e.name, m.name
FROM sports as s, events as e, matches as m
WHERE s.name = 'Football'
其中运动->事件->比赛具有1->n关系
- Match有一个事件id外键
- 事件具有sport_id外键
- 体育是根
+----------+-------------+----------------------+
| name | name | name |
-------------------------------------------------
|Football | World Cup | England vs Germany |
|Football | World Cup | Argentina vs France |
| ... | ... | ... |
-------------------------------------------------
我想在不使用DB:Raw的情况下将其转换为Laravel查询生成器查询,我有点困惑,因为文档中显示的所有示例都以DB:table(blablabla)开头,它似乎只接受1个表作为参数。
大概是
$events = DB::table('sports as s', 'events as e')
->select('s.name', 'e.name')
->where('s.name', '=', 'Football')
->get();
说e.name被认为是未知的。
我在这里读到了一些答案,它们都使用了DB:Raw或一些奇怪的连接
所以…你们知道Laravel的查询生成器处理这些查询的优雅方法吗?还是我必须坚持DB:Raw
提前谢谢 我相信您要做的是在三个表之间创建一个并集 从 unionAll方法也可用,并且具有相同的方法 作为工会签字
如果您想查询matches表中的比赛,然后使用match_id=event_id等加入比赛的事件,则可以使用联接。在浪费了相当长的时间后,我发现:
- 在多个表上使用SELECT WHERE而不是显式联接被认为是一种不好的做法,本质上是为了代码的可读性
- 如果不使用DB:raw,Laravel的查询生成器可能无法实现我想要的(糟糕的做法)
- 解决我的问题的正确方法是:
$events = DB::table('sports as s') ->join ('events as e', 'e.sport_id', '=' , 's.id') ->join ('matches as m', 'm.event_id', '=' , 'e.id') ->select('s.name as sname', 'e.name as ename', 'm.name as mname') ->get();
- 当字段名称相同时,您必须为SELECT中的名称添加别名,否则所有相同的名称只会得到一列(这就是我浪费了很多时间的地方:)
- 我尝试了Yii框架,“不良实践方式”和join方法都很好:
$query = (new \yii\db\Query()) ->select(['sport_name' => 's.name','event_name' => 'e.name']) ->from(['s' => 'sports','e' => 'events']) ->where(['s.name' => 'Football']) ->all();
再见。体育、赛事和比赛之间有关系吗?你说得对,对不起,我忘了说这个
$query = (new \yii\db\Query())
->select(['sport_name' => 's.name','event_name' => 'e.name'])
->from(['s' => 'sports','e' => 'events'])
->where(['s.name' => 'Football'])
->all();