Соедините таблицу несколько раз с другой таблицей, которая может иметь или не иметь эти значения - PullRequest
0 голосов
/ 17 февраля 2012

У меня есть три таблицы:

| items
--------
id
quantity
size_attribute_value_id
color_attribute_value_id
type_attribute_value_id

| attribute_values (instance of an attribute, like red, xsmall)
--------
id
attribute_id
name

| attributes (attribute category, like color, size)
id
name 

Любая комбинация из трех атрибутов (размер, цвет, тип) может сделать допустимый элемент. Поэтому я хочу иметь возможность запрашивать все комбинации трех атрибутов, а также включать уже существующие элементы из таблицы элементов. Идея заключается в том, что я хочу получить набор результатов всех существующих элементов и всех возможных допустимых будущих элементов. Например, даже если таблица предметов полностью пуста, я все равно должен получить результаты несуществующих, но допустимых предметов с количеством 0.

Допустимые значения атрибута: 1, 2, 4.

В качестве начала я попробовал следующее правое соединение:

SELECT i.*, av1.*, av2.*, av3.*
FROM items i 
RIGHT OUTER JOIN attribute_values av1 ON av1.attribute_id = 2 AND av1.id = i.size_attribute_value_id
RIGHT OUTER JOIN attribute_values av2 ON av2.attribute_id = 4 AND av2.id = i.color_attribute_value_id
RIGHT OUTER JOIN attribute_values av3 ON av3.attribute_id = 1 AND av3.id = i.type_attribute_value_id;

Но он возвращает только около 200 строк, когда их должно быть больше 1000.

Любая помощь, даже если это только точка в правильном направлении, приветствуется.

Ответы [ 2 ]

1 голос
/ 18 февраля 2012
SELECT a1.name as `type`, a2.name as `size`, a4.name as `color`, SUM(COALESCE( i.quantity , 0 ) ) as quantity
FROM (attribute_values a1, attribute_values a2, attribute_values a4)
LEFT JOIN items i
ON i.type_attribute_value_id = a1.id
AND i.size_attribute_value_id = a2.id
AND i.color_attribute_value_id = a4.id
WHERE a1.attribute_id = 1 AND a2.attribute_id = 2 AND a4.attribute_id = 4
GROUP BY a1.name, a2.name, a4.name

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

1 голос
/ 17 февраля 2012

Я думаю, что это должно сделать -

SELECT *
FROM (SELECT * FROM attribute_values WHERE attribute_id = 4) AS `color`
INNER JOIN (SELECT * FROM attribute_values WHERE attribute_id = 2) AS `size`
INNER JOIN (SELECT * FROM attribute_values WHERE attribute_id = 1) AS `type`
LEFT JOIN items
    ON `color`.`id` = `items`.`color_attribute_value_id`
    AND `size`.`id` = `items`.`size_attribute_value_id`
    AND `type`.`id` = `items`.`type_attribute_value_id`

Я переписал этот запрос, чтобы избежать производных таблиц. Это должно работать лучше.

SELECT color.name, size.name, type.name, IFNULL(items.quantity, 0) AS quantity
FROM attribute_values AS `color`
INNER JOIN attribute_values AS `size`
    ON size.attribute_id = 2
INNER JOIN attribute_values AS `type`
    ON type.attribute_id = 1
LEFT JOIN items
    ON `color`.`id` = `items`.`color_attribute_value_id`
    AND `size`.`id` = `items`.`size_attribute_value_id`
    AND `type`.`id` = `items`.`type_attribute_value_id`
WHERE color.attribute_id = 4;
...