【问题标题】:how join laravel tables to get non intersected data如何连接 laravel 表以获得非交叉数据
【发布时间】:2022-11-23 23:01:45
【问题描述】:

在我的Laravel 应用程序中,我有 3 个表:usersdocumentstype_documents,用户有多个文档,文档有一个 type_document

| Documents       | 
| --------        |
| id              | 
| file            | 
| type_document_id| 
| user_id         | 

| type_documents | 
| --------       |
| id             | 
| name           | 

| users          | 
| --------       |
| id             | 
| name           | 
| type_document_d| 

我想为eloquent的当前用户选择documents表中未使用的类型
我尝试这样做,但它给了我使用过的 type_documents :

$document_types = TypeDocument::leftJoin('docments' , function ($join) {
                    $join->on('type_documents.id', '=', 'douments.type_document_id')
                         ->where('documents.user_id', auth()->id());
                })
                ->applyFilters($request->all())
                ->latest()
                ->paginateData($limit);

我使用 Laravel 版本 8

【问题讨论】:

  • 您是否定义了 TypeDocument 和 User Models 之间的关联方法?

标签: php sql laravel join eloquent


【解决方案1】:

检查此解决方案

TypeDocument::whereNotIn('id', function($query){

    $query->select('type_document_id')
    ->from(with(new Documents)->getTable())
    ->where('type_document_id', $query->id)
    ->where('user_id', auth()->id());
        
})->get();

【讨论】:

  • 我在 `->where('type_document_id', $query->id)` 中得到 undefined property id
【解决方案2】:

使用在TypeDocument::classUser::class 之间定义的Eloquent relation,如下所示:

类型文档.php

public function users()
{
    return $this->belongsToMany(User::class, 'documents', 'type_document_id', 'user_id')->withPivot('file');
}

您可以像这样轻松获得未链接到特定用户的类型文档

TypeDocument::whereDoesntHave('users', function($userQuery) {
        $userQuery->where('users.id', '=', auth()->id());
    })  
    ->applyFilters($request->all())
    ->latest()
    ->paginateData($limit);

如果你想使用两步关系,你可以这样定义它:

类型文件.php

public function documents()
{
    return $this->hasMany(Document::class);
}

文档.php

public function user()
{
    return $this->belongsTo(User::class);
}

并使用关系像这样查询它:

TypeDocument::whereDoesntHave('documents.user', function($userQuery) {
        $userQuery->where('users.id', '=', auth()->id());
    })  
    ->applyFilters($request->all())
    ->latest()
    ->paginateData($limit);

【讨论】:

  • 不是多对多的关系,typ_document和user之间没有关系
  • @MAHAOUEGHLANI 您拥有的结构是多对多关系。两个带有 ID 的表和另一个带有两个外部 ID 的数据透视表到另外两个表。这是数据透视表的定义。无论哪种方式,这种关系都应该有效。你也可以定义两步关系,有多个和属于相反。
  • @MAHAOUEGHLANI 使用关系和 erhan 的解决方案之间的区别在于它只运行一个带连接的查询,而不是 2 个带嵌套的查询。
【解决方案3】:

您是否尝试过 whereNotExists() 或 whereNotIn() 而不是 leftJoin()?

例如:

<?php
// whereNotIn
$types = TypeDocument::whereNotIn('id', function($query) {
    $query->select('type_document_id')
          ->from('documents')
          ->where('user_id', auth()->id);
})->get();
<?php
// whereNotExists
$types = TypeDocument::whereNotExists(function($query) {
    $query->select(DB::raw(1))
          ->from('documents')
          ->whereRaw('type_documents.id = documents.type_document_id')
          ->where('user_id', '=', Auth::user()->id);
})->get();
<?php
// leftJoin
$types = TypeDocument::leftJoin('documents', function($join) {
    $join->on('type_documents.id', '=', 'documents.type_document_id')
         ->where('user_id', '=', Auth::user()->id);
})->whereNull('documents.type_document_id')->get();

试试这些!

【讨论】:

  • 感谢whereNotIn 的第一个解决方案工作正常:)
  • 我很高兴它对你有用:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-11
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 2018-07-13
  • 1970-01-01
  • 2022-09-27
相关资源
最近更新 更多