Эта тема связана с моим превью один Соединить две таблицы со всеми записями
Сейчас я пытаюсь объединить 3 или более таблиц в моем коде контроллера Laravel и просмотреть их в одном Datatable.
Таблица 1
+--------------------+---------+
| 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 |
+--------------------+---------+
Таблица 2
+--------------------+---------+
| 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 |
+--------------------+---------+
таблица3
+--------------------+---------+
| 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 таблиц. Он работает с нами ожидаемо, как в таблице выше:
$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();
Теперь я попытался добавить 3-й столбец в переменную $results3
и объединить его с другими:
$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;
Вы можете найти его в скрипке https://www.db-fiddle.com/f/eJsPZijRnQFGXugLGHnn93/0
ПРИМЕЧАНИЕ. Я предположил, что нулевые значения, отображаемые как «-», являются просто форматированием вывода. Если это не так, вывод с NULL можно преобразовать в '-'.
ПРИМЕЧАНИЕ 2: я не знаю, как конвертировать в код Laravel/PHP, надеюсь, у вас будет идея получше.
@HristianYordanov Это таблица1, таблица2, таблица3. Я только что изменил имена обратно.
Что такое to1,to2,to3, ts?