Php 当某些字段没有外键时,Laravel使用JSON字段连接表
我想通过存储在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
事务
:
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