动态连接 laravel 中的多个表
dynamically join multiple tables in laravel
所以我有一个像这样的table
如您所见,现有的 table 名称几乎相似,每个 table
具有相同的 column
结构,每个 table 只有一个数据月份,示例 air_message2021_01
只有一月份的数据,air_message2021_02
只有二月份的数据等等
在我的项目中,需要通过 JOIN
一些现有的 table 搜索数据,但像这样动态地搜索数据。
图中可以看到飞机id字段,年份,from date包含月日字段,to date包含月日字段,from time字段和to time字段。
因为每个table只有1个月的数据,而用户可以搜索时间跨度为6个月的数据,所以我不得不动态合并table,因为系统不会知道用户要查找的时间范围。
例子
User1搜索数据飞机ID BTK7369从2021-01-12到2021-04-20
这意味着我必须加入 air_message2021_01
、air_message2021_02
、air_message2021_03
和 air_message2021_04
User2搜索数据飞机ID BTK7552从2021-05-27到2021-08-09
这意味着我必须加入 air_message2021_05
、air_message2021_06
、air_message2021_07
和 air_message2021_08
如何解决?
谢谢
air_message*
table 的型号您可以声明为:
class AirMessageRead extends Model
{
/**
* Name base table
*
* @var string
*/
protected $baseTable = 'air_message';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = '';
/**
* For Read.
*
* @var string
*/
public $exists = true;
/**
* AirMessageRead constructor.
*
* @param int $time
* @return void
*/
public function __construct($time)
{
$this->table = $this->getTableName($time);
}
/**
* Get table name
*
* @param int $time
* @return string
*/
public function getTableName($time)
{
return $this->baseTable . $time;
}
}
在 service
上,您将范围日期转换为数组 () 和 onion :
use Carbon\CarbonPeriod;
private function getTimeRange($start, $end)
{
foreach (CarbonPeriod::create($start, '1 month', $end) as $month) {
$months[] = $month->format('Y_m');
}
return $months;
}
private function getTablesForQuery($start, $end)
{
$months = $this->getTimeRange($start, $end);
$mergeTables = array_map(fn($month) => new AirMessageRead($month), $months);
foreach ($mergeTables as $table) {
if (isset($query)) {
$query = $query->union($table);
} else {
$query = $table;
}
}
return $query
}
然后吃洋葱 tables :
// $query is model for you
$model = $this->getTablesForQuery('2021-01-12', '2021-04-20');
您可以在模型
上添加检查是否存在table的功能
所以我有一个像这样的table
如您所见,现有的 table 名称几乎相似,每个 table
具有相同的 column
结构,每个 table 只有一个数据月份,示例 air_message2021_01
只有一月份的数据,air_message2021_02
只有二月份的数据等等
在我的项目中,需要通过 JOIN
一些现有的 table 搜索数据,但像这样动态地搜索数据。
图中可以看到飞机id字段,年份,from date包含月日字段,to date包含月日字段,from time字段和to time字段。
因为每个table只有1个月的数据,而用户可以搜索时间跨度为6个月的数据,所以我不得不动态合并table,因为系统不会知道用户要查找的时间范围。
例子
User1搜索数据飞机ID BTK7369从2021-01-12到2021-04-20
这意味着我必须加入 air_message2021_01
、air_message2021_02
、air_message2021_03
和 air_message2021_04
User2搜索数据飞机ID BTK7552从2021-05-27到2021-08-09
这意味着我必须加入 air_message2021_05
、air_message2021_06
、air_message2021_07
和 air_message2021_08
如何解决?
谢谢
air_message*
table 的型号您可以声明为:
class AirMessageRead extends Model
{
/**
* Name base table
*
* @var string
*/
protected $baseTable = 'air_message';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = '';
/**
* For Read.
*
* @var string
*/
public $exists = true;
/**
* AirMessageRead constructor.
*
* @param int $time
* @return void
*/
public function __construct($time)
{
$this->table = $this->getTableName($time);
}
/**
* Get table name
*
* @param int $time
* @return string
*/
public function getTableName($time)
{
return $this->baseTable . $time;
}
}
在 service
上,您将范围日期转换为数组 () 和 onion :
use Carbon\CarbonPeriod;
private function getTimeRange($start, $end)
{
foreach (CarbonPeriod::create($start, '1 month', $end) as $month) {
$months[] = $month->format('Y_m');
}
return $months;
}
private function getTablesForQuery($start, $end)
{
$months = $this->getTimeRange($start, $end);
$mergeTables = array_map(fn($month) => new AirMessageRead($month), $months);
foreach ($mergeTables as $table) {
if (isset($query)) {
$query = $query->union($table);
} else {
$query = $table;
}
}
return $query
}
然后吃洋葱 tables :
// $query is model for you
$model = $this->getTablesForQuery('2021-01-12', '2021-04-20');
您可以在模型
上添加检查是否存在table的功能