2015-10-15 2 views
0

Как выбрать все строки по id из второй таблицы? На данный момент он выбирает только последнюю строку из второй таблицы, если id совпадает.SQL INNER JOIN выбирает только одну, последнюю строку из второй таблицы, даже если id соответствует

Запрос:

SELECT 

categories.category_id, 
categories.category_name, 
subcategories.subcategory_name, 
categories.category_data, 
categories.category_icon 

FROM categories INNER JOIN subcategories ON 

subcategories.category_id=categories.category_id"; 

Полный код:

public static function getAllCategories() 
{ 
    $database = DatabaseFactory::getFactory()->getConnection(); 

    $sql = " 
    SELECT c.category_id 
     , c.category_name 
     , s.subcategory_name 
     , c.category_data 
     , c.category_icon 
     FROM categories c 
     JOIN subcategories s 
     ON s.category_id = c.category_id; 
    "; 

    $query = $database->prepare($sql); 
    $query->execute(); 

    $all_categories = array(); 

    foreach ($query->fetchAll() as $category) { 

     array_walk_recursive($category, 'Filter::XSSFilter'); 

     $all_categories[$category->category_id] = new stdClass(); 
     $all_categories[$category->category_id]->category_id = $category->category_id; 
     $all_categories[$category->category_id]->category_data = $category->category_data; 
     $all_categories[$category->category_id]->category_icon = $category->category_icon; 
     $all_categories[$category->category_id]->category_name = $category->category_name; 
     $all_categories[$category->category_id]->subcategory_name = $category->subcategory_name; 
    } 

    return $all_categories; 
} 

Фото:

Это то, что я должен получить

enter image description here

И это то, что я есть

enter image description here

Первая таблица правильно выбирает все строки, но вторая таблица выбирает только последнюю строку, если ид спичек. Как выбрать все строки из второй таблицы?

Извините за плохой английский, и спасибо за любые ответы.

+0

использовать LEFT JOIN для всех ROW в таблице слева –

+0

это не работает. LEFT JOIN выбирает все строки из таблицы категорий, но сохраняет их для таблицы подкатегорий. Он выбирает только одну последнюю строку для второй таблицы. – Tauras

+0

Это должно выбрать все соответствующие категории и подкатегории. Можете ли вы сделать sqlfiddle с образцами данных и объяснить, что вы ожидаете от того, что он производит? – Barmar

ответ

1

Запрос:

SELECT 

categories.category_id, 
categories.category_name, 
subcategories.subcategory_id, 
subcategories.subcategory_name, 
categories.category_data, 
categories.category_icon 

FROM categories INNER JOIN subcategories ON 

subcategories.category_id=categories.category_id"; 

EDIT

$subCat = array(); 
foreach ($query->fetchAll() as $category) { 

    array_walk_recursive($category, 'Filter::XSSFilter'); 

    $subCat[$category->category_id][] = $category->subcategory_name; 

    $all_categories[$category->category_id] = new stdClass(); 
    $all_categories[$category->category_id] = $category; 
    $all_categories[$category->category_id]->subcategory_name = (object) $subCat[$category->category_id]; 
} 

При получении данных:

<?php foreach ($this->categories as $category) { ?> 
    <?= $category->category_data; ?> 
    <?php foreach ($category->subcategory_name as $subcategory) { ?> 
     <?= $subcategory; ?> 
    <?php } ?> 
<?php } ?> 
+0

Не могли бы вы объяснить мне, зачем использовать ваш код, не нужно использовать что-то вроде этого: '' $ all_categories [$ category-> category_id] -> category_name = $ category-> category_name; '' для отображения данных? Поскольку я показываю его так: '' category as $ category) {?> category_data; ?> '' – Tauras

+0

@Tauras '(array)' преобразует объект в ассоциативный массив. Это так же, как если бы вы использовали PDO :: ATTR_DEFAULT_FETCH_MODE => PDO :: FETCH_ASSOC'. – Barmar

+0

Заменить '$ all_categories [$ category-> category_id] = new stdClass();' с '$ all_categories [$ category-> subcategory_id] = new stdClass();' Сделайте это для всех '$ all_categories [$ category-> category_id] ' Вам нужно заменить' category_id' на 'subcategory_id'. Кроме того, вам нужно включить 'subcategories.subcategory_id' в свой выбор поля. –

1

Проблема в вашем PHP. Каждый раз через цикл вы замените$allCategories[$category->category_id] с данными из текущей строки. Поэтому, когда цикл завершен, он содержит только данные из последней строки.

Вы должны сделать многомерный массив. Когда строка содержит ту же категорию, что и предыдущая строка, нажмите новый объект на массив.

foreach ($query->fetchAll() as $category) { 

    array_walk_recursive($category, 'Filter::XSSFilter'); 

    if (!isset($allCategories[$category->category_id])) { 
     $allCategories[$category->category_id] = array(); 
    } 
    $all_categories[$category->category_id][] = $category; 
} 

Там нет необходимости, чтобы сделать новый объект stdClass и скопировать каждое свойство, так как fetchAll возвращает новый объект для каждой строки. Вы можете просто поместить этот объект в массив.

+0

Это дает мне ошибки. Один из них: '' Примечание: попытка получить свойство не-объекта in'' – Tauras

+0

Вы установили режим выборки в 'PDO :: FETCH_OBJ'? – Barmar

+0

Я использую тот же синтаксис объекта, что и ваш исходный код. Я не вижу, как моя будет получать эту ошибку, если вы этого не сделали. – Barmar