Получение информации из двух таблиц Mysql - PullRequest
1 голос
/ 21 февраля 2012

Я использую Codeigniter и пытаюсь вызвать информацию из двух таблиц:

Product: id, имя, цена, описание, typeId

Product_Type: tCategory, tName

Я пытаюсь получить всю информацию из Product и использовать Product.typeID для соответствия таблице Product_Type и только вернуть tName.В большинстве случаев в таблице Product_Type будет как минимум 3 строки с одинаковым typeID.Пример:

Товар 1 будет красной рубашкой за 20 долларов, а для типа мне понадобятся Large, Medium и Small.

Я пытался сделать это с JOIN, но он дает мне 3 типа, которые мне нужны, но также дублирую информацию о футболке 3 раза.

Вот мой код:

$this->db->select('product.id, product.name, product.price, product.description, product_type.tName');  
$this->db->from('product');
$this->db->where('perm_name', $id);
$this->db->join('product_type', 'product_type.tCategory = product.typeId', 'LEFT OUTER');
$query = $this->db->get(); 

Любая помощь будет принята с благодарностью.

РЕДАКТИРОВАТЬ:

Array
(
    stdClass Object
        (
            [id] => 2
            [name] => Tshirt 1
            [price] => 20
            [description] => Awesome tshirt
            [tName] => 1
    )

)

Array
(
    [0] => stdClass Object
        (
            [tCategory] => 1
            [tName] => Small
    )

    [1] => stdClass Object
        (
            [tCategory] => 1
            [tName] => Medium
    )
    [2] => stdClass Object
        (
            [tCategory] => 1
            [tName] => Large
    )

)

1 Ответ

0 голосов
/ 21 февраля 2012

Чтобы строка продукта содержала столбец types, который заполняется строками 2-й таблицы, вы можете либо объединить обе таблицы, либо поиграть с группой:

SELECT 
    product.id, 
    max(product.name) as name, 
    max(product.price) as price, 
    max(product.description) as description, 
    group_concat(product_types.tName) as types

FROM
    product

LEFT JOIN
    product_type ON product.tName = product_types.tCategory

GROUP BY product.id

За Максом нет волшебства (product.name). Вы не можете использовать столбцы в предложении выбора, которые не входят в групповое предложение или объединены. Поскольку product.id является первичным ключом, мы получим только один product.name для каждого product.id, поэтому нам не важно, какой из 3 product.name (из объединения с 3 типами) будет выбран. они все одинаковы. мы могли бы даже написать любое (product.name) в предложении select, но я не думаю, что MySQL поддерживает это. =)

или выполните коррелированный подзапрос ~

SELECT 
    product.id, 
    product.name, 
    product.price, 
    product.description, 
    (SELECT 
         group_concat(product_types.tName)
     FROM product_types
     WHERE product.tName = product_types.tCategory
     GROUP BY product_types.tCategory
    ) as types

FROM
    product

Я предлагаю использовать первый запрос, так как MySQL будет легче оптимизировать. для записи: я не тестировал эти запросы, поэтому возможно, что они нуждаются в некоторой настройке. просто дай мне знать.

Edit1: дальнейшее объяснение использования max ()

В следующем запросе нам не разрешено использовать столбец name, поскольку мы сгруппированы только по столбцу id.

SELECT
    id,
    name /* not allowed */

FROM
    product

GROUP BY id

мы можем выбирать только те столбцы, которые находятся в group by -пункте. мы также можем использовать столбцы, которые не входят в group by -класс, хотя агрегатные функции, такие как max и group_concat.

Чтобы решить эту проблему, мы можем просто добавить столбец name в group by -классу

SELECT
    id,
    name /* ok because it's in group by */

FROM
    product

GROUP BY id, name

если у нас теперь есть разные значения для name, мы получим более одного кортежа в результате, например ::

Для таблицы product (id, name) = {(1, Алиса), (1, Боб)} мы получаем результат

1, Alice
1, Bob

потому что мы сгруппировали оба столбца.

2-й подход использует агрегатную функцию, например, max:

SELECT
    id,
    max(name) /* ok because it's aggregated */

FROM
    product

GROUP BY id

Для таблицы product (id, name) = {(1, Алиса), (1, Боб)} мы получаем результат

1, Bob /* max(Alice,Bob) = Bob, because A < B */

В вашем примере я предположил, что столбец product.id является первичным ключом и, следовательно, уникальным. Это означает, что мы не можем иметь разные значения в столбце name для одинаковых значений в столбце id. {(1, Alice), (1, Bob)} невозможно, но возможно {(1, Alice), (2, Bob)}. Если мы GROUP BY product.id сейчас, мы получим значение для product.name для каждого кортежа в группе. Но поскольку id определяет name, все эти значения одинаковы:

SELECT 
    product.id, 
    product.name, 
    product_type.tName,

FROM
    product

LEFT JOIN
    product_type ON product.tName = product_types.tCategory

приведет к

(1, "White T-Shirt", Small),
(1, "White T-Shirt", Medium),
(1, "White T-Shirt", Large),
(2, "Black T-Shirt", Small),
(2, "Black T-Shirt", Medium),
(2, "Black T-Shirt", Large)

после группировки по product.id результат будет выглядеть как

(1, F("White T-Shirt", "White T-Shirt", "White T-Shirt"), 
     G(Small, Medium, Large)),
(2, F("Black T-Shirt", "Black T-Shirt", "Black T-Shirt"), 
     G(Small, Medium, Large))

, где F и G - агрегатные функции, используемые в предложении select. для F не имеет значения, какое значение мы используем, они все одинаковы. поэтому мы просто использовали max. для g мы использовали group_concat, чтобы объединить все значения вместе.

следовательно

F("White T-Shirt", "White T-Shirt", "White T-Shirt") = "White T-Shirt"
F("Black T-Shirt", "Black T-Shirt", "Black T-Shirt") = "Black T-Shirt"
G(Small, Medium, Large) = "Small, Medium, Large"

это приведет к

(1, "White T-Shirt", "Small, Medium, Large"),
(2, "Black T-Shirt", "Small, Medium, Large")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...