SQL: запрос связанных данных из нескольких таблиц - PullRequest
0 голосов
/ 02 марта 2019

У меня есть 4 таблицы, которые все связаны друг с другом таким образом, что: TB1 <- TB2 <- TB3 <- TB4 означает, что TB4 содержит элементы, принадлежащие одной строке в TB3, TB3 содержит элементы, которые принадлежатодна строка в TB2 и, наконец, TB2 содержит данные, принадлежащие одной строке в TB1.я сделал эту иллюстрацию, чтобы попытаться сделать ее более понятной <a href="https://i.stack.imgur.com/437L7.png" rel="nofollow noreferrer">enter image description here

(редактировать: БД должна была быть ТБ, как в таблице)

Я пытался добитьсяэто с помощью подзапросов следующим образом:

SELECT TB1.id AS TB1_ID, 
    (SELECT TB2.id AS TB2_ID,
        (SELECT TB3.id AS TB3_ID,
            (SELECT TB4.id AS TB4_ID
            FROM `TB4` AS TB4 WHERE TB4.TB3_id = TB3.id) AS C
        FROM `TB3` AS TB3 WHERE TB3.TB2_id = TB2.id) AS B
    FROM `TB2` AS TB2 WHERE TB2.TB1_id = TB1.id) AS A
FROM `TB1` AS TB1

все же моя логика должна быть ошибочной: или что-то мне не хватает в запросе связанных данных: так как это возвращает ноль, хотя я знаю, что таблицы содержат необходимыеинформация, необходимая для создания такой перекрестной комбинации.

Желаемый результат - набор вложенных массивов в массиве: один вложенный массив для каждой таблицы.так что в итоге мы получим такую ​​структуру:

{*, A{*, B{*, C{*} } } }

, чтобы каждая строка из TB1 содержала многомерный массив элементов из TB2 в качестве переменной, а каждая форма строки TB2 содержала многомерный массив элементов из TB3 какэлемент и так далее ...

Я также пытался собрать всю информацию в виде отдельных запросов, а затем объединить их в JS, однако оказалось довольно тяжелым: поэтому я был бы очень признателен, если бы кто-нибудь знал, каксделать это правильно - большое спасибо заранее

PS.я пытаюсь это в моей локальной среде, с помощью XAMPP: это создает проблему?

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Вот попытка, которая использует функции JSON и другие вещи, которые должны работать в последней версии 5.7.

Но не спрашивайте об этом, потому что я обнаружил из этого эксперимента, что имеет дело с вложенными json в MySql5.7 - настоящая пита.

Пример данных:

drop table if exists Table1;
drop table if exists Table2;
drop table if exists Table3;
drop table if exists Table4;

create table Table1 (id int primary key, col1 varchar(30));
create table Table2 (id int primary key, tbl1_id int, col1 varchar(30));
create table Table3 (id int primary key, tbl2_id int, col1 varchar(30));
create table Table4 (id int primary key, tbl3_id int, col1 varchar(30));

insert into Table1 (id, col1) values
(101, 'A1'),(102, 'A2'),(103, 'A3'),(104, 'A4');

insert into Table2 (id, tbl1_id, col1) values
(201, 101, 'B1'), (202, 102, 'B2'),(203, 103, 'B3');

insert into Table3 (id, tbl2_id, col1) values
(301, 201, 'C1'),(302, 202, 'C2');

insert into Table4 (id, tbl3_id, col1) values
(401, 301, 'D1'), (402, 301, 'D2');

Запрос:

SELECT t1.id AS t1id, 
GROUP_CONCAT(REPLACE(JSON_OBJECT(t1.id, JSON_ARRAY(t1.col1)),']}',', '),
IFNULL(
(
  SELECT 
  GROUP_CONCAT(
   REPLACE(JSON_OBJECT(t2.id, JSON_ARRAY(t2.col1)),']}',', '),
   IFNULL(
   (
    SELECT 
    GROUP_CONCAT(
     REPLACE(JSON_OBJECT(t3.id, JSON_ARRAY(t3.col1)),']}',', '),
     IFNULL(
     (
       SELECT 
       CONCAT('[', 
        IFNULL(GROUP_CONCAT(JSON_OBJECT(t4.id, JSON_ARRAY(t4.col1))),''), 
        ']') D
       FROM Table4 t4
       WHERE t4.tbl3_id = t3.id
       GROUP BY t4.tbl3_id
     ), '[]'), ']}') C
    FROM Table3 t3
    WHERE t3.tbl2_id = t2.id
    GROUP BY t3.tbl2_id
   ), '[]'), ']}') B
  FROM Table2 t2
  WHERE t2.tbl1_id = t1.id
  GROUP BY t2.tbl1_id
 ), '[]'), ']}') A
FROM Table1 t1
GROUP BY t1.id;

Возвраты:

id  A
101 {"101": ["A1", {"201": ["B1", {"301": ["C1", [{"401": ["D1"]},{"402": ["D2"]}]]}]}]}
102 {"102": ["A2", {"202": ["B2", {"302": ["C2", []]}]}]}
103 {"103": ["A3", {"203": ["B3", []]}]}
104 {"104": ["A4", []]}

Тест по дБ <> скрипка здесь

0 голосов
/ 02 марта 2019

Я думаю, что вам нужна серия из JOIN s:

SELECT TB1.id AS TB1_ID, TB2.id AS TB2_ID, TB3.id AS TB3_ID, TB4.id AS TB4_ID
FROM TB1
JOIN TB2 ON TB2.TB1_ID = TB1.ID
JOIN TB3 ON TB3.TB2_ID = TB2.ID
JOIN TB4 ON TB4.TB3_ID = TB3.ID

Затем вы можете построить желаемую структуру в PHP, используя что-то вроде:

$sql = "SELECT TB1.id AS TB1_ID, TB2.id AS TB2_ID, TB3.id AS TB3_ID, TB4.id AS TB4_ID
FROM TB1
JOIN TB2 ON TB2.TB1_ID = TB1.ID
JOIN TB3 ON TB3.TB2_ID = TB2.ID
JOIN TB4 ON TB4.TB3_ID = TB3.ID";
$result = $conn->query($sql) or die($conn->error);
$output = array();
while ($row = $result->fetch_assoc()) {
    $tb1_id = $row['TB1_ID'];
    $tb2_id = $row['TB2_ID'];
    $tb3_id = $row['TB3_ID'];
    $tb4_id = $row['TB4_ID'];
    if (isset($output[$tb1_id][$tb2_id][$tb3_id])) {
        $output[$tb1_id][$tb2_id][$tb3_id][$tb4_id] = array();
    }
    elseif (isset($output[$tb1_id][$tb2_id])) {
        $output[$tb1_id][$tb2_id][$tb3_id] = array($tb4_id => array());
    }
    elseif (isset($output[$tb1_id])) {
        $output[$tb1_id][$tb2_id] = array($tb3_id => array($tb4_id => array()));
    }
    else {
        $output[$tb1_id] = array($tb2_id => array($tb3_id => array($tb4_id => array())));
    }
}
...