Как мне сгруппировать одно значение в виде массива из mysql «многие ко многим»? - PullRequest
0 голосов
/ 05 марта 2019

У меня есть три таблицы, одна для бизнес-списков, одна для Dining_types и одна для Dining_Listing_types.

business_listings:

 +--------+------------------+------------------+
 |  id    |  business_type   |   business_name  |
 +--------+------------------+------------------+
 |  1     |       1          |   china house    |
 +--------+------------------+------------------+

Dining_Listing_types:

 +--------+------------------+------------------+
 |  id    |    listing_id    |    type_id       |
 +--------+------------------+------------------+
 |   1    |        1         |        1         |
 +--------+------------------+------------------+
 |   2    |        1         |        3         |
 +--------+------------------+------------------+

Dining_types:

 +--------+------------------+
 |  id    |      type        |
 +--------+------------------+
 |  1     |   Asian          |
 +--------+------------------+
 |  2     |   Italian        |
 +--------+------------------+
 |  3     |   Chinese        |
 +--------+------------------+

Как видите, список может иметь несколько типовс таблицей Dining_listing_types, выступающей в качестве таблицы "посредник".

Однако, когда я пытаюсь использовать соединение в своем запросе, я получаю две записи

SELECT bl.id AS id, bl.business_name AS name, dt.type AS type
FROM business_listings bl 
JOIN dining_listing_types dlt ON bl.id = dlt.listing_id 
JOIN dining_types dt ON dlt.type_id = dt.id

Результат:

 array(2) { [0]=> object(stdClass)#7 (3) { ["id"]=> string(1) "1" ["name"]=> 
 string(23) "China House" ["type"]=> string(5) "Asian" } [1]=> 
 object(stdClass)#8 (3) { ["id"]=> string(1) "1" ["name"]=> string(23) "China 
 House" ["type"]=> string(18) "Chinese" } }

Я не хочу этого.Я попробовал GROUP BY bl.id, и я получил одну запись, но другой тип отсутствовал:

SELECT bl.id AS id, bl.business_name AS name, dt.type AS type
FROM business_listings bl 
JOIN dining_listing_types dlt ON bl.id = dlt.listing_id 
JOIN dining_types dt ON dlt.type_id = dt.id
GROUP BY bl.id

Результат:

 array(1) { [0]=> object(stdClass)#7 (3) { ["id"]=> string(1) "1" ["name"]=> 
 string(23) "China House" ["type"]=> string(5) "Asian" } }

Результат, который я хочу:

array(1) { [0]=> object(stdClass)#7 (3) { ["id"]=> string(1) "1" ["name"]=> 
string(23) "China House" ["type"]=> array(2) ["Asian", "Chinese"] } }

Ответы [ 2 ]

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

Исходя из ваших выходных данных, я предполагаю, что вы используете PHP.Если вы используете класс mysqli (с подключением $conn), вы можете достичь желаемого с помощью чего-то подобного (используя GROUP_CONCAT, как предложено @rickdenhaan):

$sql = 'SELECT bl.id AS id, bl.business_name AS name, GROUP_CONCAT(dt.type) AS type
FROM business_listings bl 
LEFT JOIN dining_listing_types dlt ON bl.id = dlt.listing_id 
LEFT JOIN dining_types dt ON dlt.type_id = dt.id
GROUP BY bl.id, bl.business_name';
$result = $conn->query($sql) or die($conn->error);
while ($obj = $result->fetch_object()) {
    $obj->type = explode(',', $obj->type);
    // do something with $obj
}
0 голосов
/ 05 марта 2019

Как прокомментировал @ rickdenhaan , GROUP_CONCAT(), кажется, довольно близко к тому, что вы ищете.Это не генерирует массив type s, а разделенный запятыми список.Еще один интересный вариант - создание массива JSON, но я не уверен, что это действительно поможет.

Чтобы это работало, как вы ожидаете, вам нужно добавить business_name в список неагрегированныхстолбцы:

SELECT bl.id AS id, bl.business_name AS name, GROUP_CONCAT(dt.type) AS types
FROM business_listings bl 
INNER JOIN dining_listing_types dlt ON bl.id = dlt.listing_id 
INNER JOIN dining_types dt ON dlt.type_id = dt.id
GROUP BY bl.id, bl.business_name

Примечание: как прокомментировал @ spencer7593 , было бы неплохо использовать LEFT JOIN с вместо INNER JOIN с, если нам нужно вернуть business_listings которые не имеют отношения dining_types.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...