获取另一个表中不存在的所有项目
Posted
技术标签:
【中文标题】获取另一个表中不存在的所有项目【英文标题】:Get all items that do not exist in another table 【发布时间】:2020-08-17 18:14:57 【问题描述】:我正在使用Laravel Framework 6.16.0
,我有两个表,logos
和 companies
:
标志:
Schema::create('logos', function (Blueprint $table)
$table->bigIncrements('id');
$table->integer('companies_id')->default('999999');
$table->string('logo_path')->nullable($value = true); // path to the logo image
$table->timestamps();
);
公司:
Schema::create('companies', function (Blueprint $table)
$table->bigIncrements('id');
$table->string('symbol'); // AAPL
$table->string('name'); // company name such as Apple Inc.
$table->timestamps();
);
型号:
class Logo extends Model
protected $table = 'logos';
protected $guarded = ['id'];
public function company()
return $this->belongsTo(Company::class, 'companies_id');
class Company extends Model
protected $table = 'companies';
protected $guarded = ['id'];
我想获取logo-table
中没有徽标且徽标尚未更新为90 days
的所有符号。
我尝试了以下方法:
$symbolsWithoutLogos = DB::table('companies')
>leftJoin('logos', 'companies.id', '=', 'logos.companies_id')
->whereDate('logos.updated_at', Carbon::now()->subDays(90))
->whereNull('companies.logo_image')
->orderBy('name', 'ASC')
->get('companies.*');
此查询结果:
select `companies`.* from `companies` left join `logos` on `companies`.`id` = `logos`.`companies_id` where date(`logos`.`updated_at`) = ? order by `name` asc
但是,即使我的公司表有足够的记录,我在运行此查询时也没有得到结果:
任何建议我做错了什么?
感谢您的回复!
【问题讨论】:
我认为您应该更正您提供给我们的信息。因为首先,我看到的是“logo_path”列而不是“logo_image”列,正如您在下面的构建器中所写的那样。其次,在原始 mysql 查询中,我没有看到“logo_image”或“logo_path”。最后,您谈到获取没有徽标但最后更新徽标至少 90 天前的“符号”,这是矛盾的。 【参考方案1】:您可以使用 Eloquent 来实现这一点,而不是使用左连接和 DB 外观。
我猜 Company 和 Logo 之间的关系是 1:1 或 1:n。如果我们假设它是 1:1,那么您的查询将如下所示:
Company::whereHas('logo', function($query)
return $query->where('date', '<', Carbon::now()->subDays(90));
)->orWhereDoesntHave('logo')->...
您应该检查:Querying relationship absence
只要我们遵循 Laravel 命名约定,我们不需要指定表名,Laravel 会从模型名中找出来。
标志模型应该是这样的:
class Logo extends Model
// protected $table = 'logos';
// not necessary, Laravel already knows to use logos table
protected $guarded = ['id'];
public function company()
// return $this->belongsTo(Company::class, 'companies_id');
// no need to specify foreign key if we follow naming convention
// foreign key should be foreign_model_singular_id
// in this case it is company_id
return $this->belongsTo(Company::class);
Company 模型也不需要指定表名,它已经知道它应该是 companies。
公司模式:
class Company extends Model
// protected $table = 'companies';
protected $guarded = ['id'];
public function logo()
return $this->hasOne(Logo::class);
请检查 $guarded 和 $fillable 属性是如何工作的。如果只有 id 设置为受保护,那么所有其他属性都是不受保护的,不确定这是否是您的意图。
完整的查询应该是:
Company::whereHas('logo', function($query)
return $query->where('updated_at', '<', Carbon::now()->subDays(90));
)->orWhereDoesntHave('logo')
->orderBy('name', 'ASC')
->get();
【讨论】:
请查看我对这两个模型的更新问题。【参考方案2】:->whereDate('logos.updated_at' whereDate 仅比较 dateTime 列的日期部分...尝试使用 carbon 中的 toDateString() ...
$symbolsWithoutLogos = DB::table('companies')
->leftJoin('logos', 'companies.id', '=', 'logos.companies_id')
->whereDate('logos.updated_at', Carbon::now()->subDays(90)->toDateString())
->whereNull('companies.logo_image')
->orderBy('name', 'ASC')->select('companies.*')
->get();
【讨论】:
以上是关于获取另一个表中不存在的所有项目的主要内容,如果未能解决你的问题,请参考以下文章