Laravel 8 中的 3 个或更多表的外部联接
Outer join 3 or more tables in Laravel 8
这个主题与我的预览一有关
我现在正在尝试在我的 Laravel 控制器代码中加入 3 个或更多 table,并在一个数据中查看它们table。
table1
+--------------------+---------+
| recordtime | tempout |
+--------------------+---------+
| 4.12.2020 10:00:00 | 1.1 |
| 4.12.2020 10:30:00 | 1.2 |
| 4.12.2020 11:00:00 | 1.3 |
| 4.12.2020 11:30:00 | 1.4 |
| 4.12.2020 12:00:00 | 1.5 |
+--------------------+---------+
table2
+--------------------+---------+
| recordtime | tempout |
+--------------------+---------+
| 4.12.2020 10:00:00 | 2.1 |
| 4.12.2020 11:00:00 | 2.3 |
| 4.12.2020 12:00:00 | 2.5 |
| 4.12.2020 13:00:00 | 2.6 |
| 4.12.2020 14:00:00 | 2.7 |
| 4.12.2020 16:00:00 | 2.9 |
+--------------------+---------+
table3
+--------------------+---------+
| recordtime | tempout |
+--------------------+---------+
| 4.12.2020 15:00:00 | 3.1 |
| 4.12.2020 16:00:00 | 3.3 |
+--------------------+---------+
需要的结果是这样的:
+--------------------+---------+---------------+---------------+
| recordtime | tempout | tempoutstamb | tempoutstamb2 |
+--------------------+---------+---------------+---------------+
| 4.12.2020 10:00:00 | 1.1 | 2.1 | - |
| 4.12.2020 10:30:00 | 1.2 | - | - |
| 4.12.2020 11:00:00 | 1.3 | 2.3 | - |
| 4.12.2020 11:30:00 | 1.4 | - | - |
| 4.12.2020 12:00:00 | 1.5 | 2.5 | - |
| 4.12.2020 13:00:00 | - | 2.6 | - |
| 4.12.2020 14:00:00 | - | 2.7 | - |
| 4.12.2020 15:00:00 | - | - | 3.1 |
| 4.12.2020 16:00:00 | - | 2.9 | 3.3 |
+--------------------+---------+---------------+---------------+
结果需要有所有记录,并以“recordtime”列为准。
我创建了 2 table 秒的代码。他正在像上面 table 中那样按照我们的预期工作:
$results2 = Tablemodel1::whereBetween('table1.recordtime', $dateScope)
->selectRaw('table1.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->leftJoin('table2', function($join){
$join->on('table1.recordtime', '=', 'table2.recordtime');
})
->groupBy('table1.recordtime');
$results = Tablemodel2::whereBetween('table2.recordtime', $dateScope)
->selectRaw('table2.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->leftJoin('table1', function($join){
$join->on('table1.recordtime', '=', 'table2.recordtime');
})
->groupBy('table2.recordtime')
->orderBy('recordtime', 'ASC')
->union($results2)
->get();
我现在尝试在 $results3
变量中添加第 3 列并将其与其他列合并:
$results2 = Tablemodel1::whereBetween('table1.recordtime', $dateScope)
->selectRaw('table1.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->leftJoin('table2', function($join){
$join->on('table1.recordtime', '=', 'table2.recordtime');
})
->groupBy('table1.recordtime');
$results3 = Tablemodel3::whereBetween('table3.recordtime', $dateScope)
->selectRaw('table3.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table3.tempout) as tempoutstamb2')
->leftJoin('table1', function($join){
$join->on('table3.recordtime', '=', 'table2.recordtime');
})
->groupBy('table3.recordtime');
$results = Tablemodel2::whereBetween('table2.recordtime', $dateScope)
->selectRaw('table2.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->leftJoin('table1', function($join){
$join->on('table1.recordtime', '=', 'table2.recordtime');
})
->groupBy('table2.recordtime')
->orderBy('recordtime', 'ASC')
->union($results2)
->union($results3)
->get();
这让我需要在列 tempoutstamb2
中的所有记录在 tempoutstamb
中被错误地传输。知道如何让它正确吗?
原始 SQL 答案也很好。
这个方法很有效:
$results2 = Tablemodel1::whereBetween('table1.recordtime', $dateScope)
->selectRaw('table1.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->selectRaw('max(table3.tempout) as tempoutstamb2')
->leftJoin('table2','table1.recordtime', '=', 'table2.recordtime')
->leftJoin('table3','table1.recordtime', '=', 'table3.recordtime')
->groupBy('table1.recordtime');
$results3 = Tablemodel3::whereBetween('table3.recordtime', $dateScope)
->selectRaw('table3.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->selectRaw('max(table3.tempout) as tempoutstamb2')
->leftJoin('table1','table1.recordtime', '=', 'table3.recordtime')
->leftJoin('table2','table2.recordtime', '=', 'table3.recordtime')
->groupBy('table3.recordtime');
$results = Tablemodel2::whereBetween('table2.recordtime', $dateScope)
->selectRaw('table2.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->selectRaw('max(table3.tempout) as tempoutstamb2')
->leftJoin('table1','table1.recordtime', '=', 'table2.recordtime')
->leftJoin('table3','table2.recordtime', '=', 'table3.recordtime')
->groupBy('table2.recordtime')
->union($results2)
->union($results3)
->orderBy('recordtime', 'ASC')
->get();
我会等待将我的答案标记为已解决,如果很快就没有其他答案使用优化代码(例如使用循环或其他东西)。
你可以用更简单的方法解决它:
select ts recordtime, max(to1) tempout, max(to2) tempoutstamb, max(to3) tempoutstamb2
from (
select ts, tempout to1, cast (null as numeric(10,1)) to2, cast (null as numeric(10,1)) to3
from table1
union all
select ts, null, tempout, null
from table2
union all
select ts, null, null, tempout
from table3
) tt
group by ts
order by ts;
您可以在 fiddle https://www.db-fiddle.com/f/eJsPZijRnQFGXugLGHnn93/0
中找到它
注意:我假设显示为“-”的空值只是输出格式。
如果不是这种情况,可以将带有 NULL 的输出转换为 '-'。
注意2:我不知道如何转换为Laravel/PHP代码,希望你有更好的主意。
这个主题与我的预览一有关
我现在正在尝试在我的 Laravel 控制器代码中加入 3 个或更多 table,并在一个数据中查看它们table。
table1
+--------------------+---------+
| recordtime | tempout |
+--------------------+---------+
| 4.12.2020 10:00:00 | 1.1 |
| 4.12.2020 10:30:00 | 1.2 |
| 4.12.2020 11:00:00 | 1.3 |
| 4.12.2020 11:30:00 | 1.4 |
| 4.12.2020 12:00:00 | 1.5 |
+--------------------+---------+
table2
+--------------------+---------+
| recordtime | tempout |
+--------------------+---------+
| 4.12.2020 10:00:00 | 2.1 |
| 4.12.2020 11:00:00 | 2.3 |
| 4.12.2020 12:00:00 | 2.5 |
| 4.12.2020 13:00:00 | 2.6 |
| 4.12.2020 14:00:00 | 2.7 |
| 4.12.2020 16:00:00 | 2.9 |
+--------------------+---------+
table3
+--------------------+---------+
| recordtime | tempout |
+--------------------+---------+
| 4.12.2020 15:00:00 | 3.1 |
| 4.12.2020 16:00:00 | 3.3 |
+--------------------+---------+
需要的结果是这样的:
+--------------------+---------+---------------+---------------+
| recordtime | tempout | tempoutstamb | tempoutstamb2 |
+--------------------+---------+---------------+---------------+
| 4.12.2020 10:00:00 | 1.1 | 2.1 | - |
| 4.12.2020 10:30:00 | 1.2 | - | - |
| 4.12.2020 11:00:00 | 1.3 | 2.3 | - |
| 4.12.2020 11:30:00 | 1.4 | - | - |
| 4.12.2020 12:00:00 | 1.5 | 2.5 | - |
| 4.12.2020 13:00:00 | - | 2.6 | - |
| 4.12.2020 14:00:00 | - | 2.7 | - |
| 4.12.2020 15:00:00 | - | - | 3.1 |
| 4.12.2020 16:00:00 | - | 2.9 | 3.3 |
+--------------------+---------+---------------+---------------+
结果需要有所有记录,并以“recordtime”列为准。
我创建了 2 table 秒的代码。他正在像上面 table 中那样按照我们的预期工作:
$results2 = Tablemodel1::whereBetween('table1.recordtime', $dateScope)
->selectRaw('table1.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->leftJoin('table2', function($join){
$join->on('table1.recordtime', '=', 'table2.recordtime');
})
->groupBy('table1.recordtime');
$results = Tablemodel2::whereBetween('table2.recordtime', $dateScope)
->selectRaw('table2.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->leftJoin('table1', function($join){
$join->on('table1.recordtime', '=', 'table2.recordtime');
})
->groupBy('table2.recordtime')
->orderBy('recordtime', 'ASC')
->union($results2)
->get();
我现在尝试在 $results3
变量中添加第 3 列并将其与其他列合并:
$results2 = Tablemodel1::whereBetween('table1.recordtime', $dateScope)
->selectRaw('table1.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->leftJoin('table2', function($join){
$join->on('table1.recordtime', '=', 'table2.recordtime');
})
->groupBy('table1.recordtime');
$results3 = Tablemodel3::whereBetween('table3.recordtime', $dateScope)
->selectRaw('table3.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table3.tempout) as tempoutstamb2')
->leftJoin('table1', function($join){
$join->on('table3.recordtime', '=', 'table2.recordtime');
})
->groupBy('table3.recordtime');
$results = Tablemodel2::whereBetween('table2.recordtime', $dateScope)
->selectRaw('table2.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->leftJoin('table1', function($join){
$join->on('table1.recordtime', '=', 'table2.recordtime');
})
->groupBy('table2.recordtime')
->orderBy('recordtime', 'ASC')
->union($results2)
->union($results3)
->get();
这让我需要在列 tempoutstamb2
中的所有记录在 tempoutstamb
中被错误地传输。知道如何让它正确吗?
原始 SQL 答案也很好。
这个方法很有效:
$results2 = Tablemodel1::whereBetween('table1.recordtime', $dateScope)
->selectRaw('table1.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->selectRaw('max(table3.tempout) as tempoutstamb2')
->leftJoin('table2','table1.recordtime', '=', 'table2.recordtime')
->leftJoin('table3','table1.recordtime', '=', 'table3.recordtime')
->groupBy('table1.recordtime');
$results3 = Tablemodel3::whereBetween('table3.recordtime', $dateScope)
->selectRaw('table3.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->selectRaw('max(table3.tempout) as tempoutstamb2')
->leftJoin('table1','table1.recordtime', '=', 'table3.recordtime')
->leftJoin('table2','table2.recordtime', '=', 'table3.recordtime')
->groupBy('table3.recordtime');
$results = Tablemodel2::whereBetween('table2.recordtime', $dateScope)
->selectRaw('table2.recordtime')
->selectRaw('max(table1.tempout) as tempout')
->selectRaw('max(table2.tempout) as tempoutstamb')
->selectRaw('max(table3.tempout) as tempoutstamb2')
->leftJoin('table1','table1.recordtime', '=', 'table2.recordtime')
->leftJoin('table3','table2.recordtime', '=', 'table3.recordtime')
->groupBy('table2.recordtime')
->union($results2)
->union($results3)
->orderBy('recordtime', 'ASC')
->get();
我会等待将我的答案标记为已解决,如果很快就没有其他答案使用优化代码(例如使用循环或其他东西)。
你可以用更简单的方法解决它:
select ts recordtime, max(to1) tempout, max(to2) tempoutstamb, max(to3) tempoutstamb2
from (
select ts, tempout to1, cast (null as numeric(10,1)) to2, cast (null as numeric(10,1)) to3
from table1
union all
select ts, null, tempout, null
from table2
union all
select ts, null, null, tempout
from table3
) tt
group by ts
order by ts;
您可以在 fiddle https://www.db-fiddle.com/f/eJsPZijRnQFGXugLGHnn93/0
中找到它注意:我假设显示为“-”的空值只是输出格式。 如果不是这种情况,可以将带有 NULL 的输出转换为 '-'。
注意2:我不知道如何转换为Laravel/PHP代码,希望你有更好的主意。