Php 当某些字段没有外键时,Laravel使用JSON字段连接表

Php 当某些字段没有外键时,Laravel使用JSON字段连接表,php,mysql,laravel,Php,Mysql,Laravel,我想通过存储在JSON字段中的外键连接两个表。该字段可以为空,因此我得到一个错误,我无法摆脱 我有一个模型事务: class Transaction extends BaseModel { protected $casts = [ 'items' => 'json', ]; items字段是json: [{"event_id":25,"article_nr":"000123","titl

我想通过存储在JSON字段中的外键连接两个表。该字段可以为空,因此我得到一个错误,我无法摆脱

我有一个模型
事务

class Transaction extends BaseModel
{
    protected $casts = [
        'items' => 'json',
    ];
items
字段是json:

[{"event_id":25,"article_nr":"000123","title":"My Event"}]
现在我想连接这些表以进行查询:

Transaction::join('events','transactions.items->event_id', '=', 'events.id')
->get();
问题是,我有许多事务类型,因此items字段不一定包含
event\u id
键,甚至可以为空

来自Eloquent的SQL查询是:

select * from `transactions` inner join `events` on json_unquote(json_extract(`transactions`.`items`, '$."event_id"')) = `events`.`id`
因此,对于带有空
项的行
-字段,我得到错误:

3141 Invalid JSON text in argument 1 to function json_extract: "The document is empty." at position 0.
有没有办法改变我的连接,只选择包含
items->event\u id
键的行

[编辑]添加了SQL原始查询

我让它工作了

在Akina的帮助下(谢谢),他提到,所有字段都必须至少填充一个空json对象:

Update transactions set items = '{}' where items = '' or items is null;
我能够通过以下方式连接表:

Transaction::select(['transactions.*'])
                ->leftJoin('events',DB::raw("json_extract(transactions.items, '$[0].event_id')"),"=","events.id")
'$[0].event\u id'
部分是此联接的专用部分,因为我的event\u id位于一个对象中,而此对象位于一个数组中:

[{"event_id":24}]
(注意外括号)

如果没有外部数组,这将很容易,我可以在没有原始sql的情况下完成,比如:

Transaction::leftJoin('events','transactions.items->event_id', '=', 'events.id')
[编辑] 最终解决方案

当通过JSON字段连接时,您将遇到性能问题。我的询问花了大约160秒

最终的解决方案是从
items
行创建一个生成的列
event\u id
。MySQL“生成的列”由其表达式自动填充,并在更新items字段时由MySQL/MariaDB自动更新

ALTER TABLE transactions ADD event_id int(10) UNSIGNED AS (JSON_UNQUOTE(items->"$[0].event_id")) STORED;
拉威尔的迁移将是

$table->bigInteger('event_id')->unsigned()->storedAs('JSON_UNQUOTE(items->"$[0].event_id")');

现在,我的查询只需要0.2秒而不是160秒。

或者甚至可以是空的。本例中的值正好是。空字符串替换为有效的JSON。例如,一个空数组。很好,现在看起来更好了。我没有任何错误。结果仍然是空的,但我想我可以克服这一点。我想我的语法错了。非常感谢。好的,下一个问题是:如果您查看数据中的括号,我的项对象是一个数组。雄辩地将其转换为json上的
内部连接事件(json提取(transactions.items,$.“[0]event\u id”)=events.id
,但我需要
json上的内部连接事件(json提取(transactions.items,$[0]”event\u id“)=events.id