Выбор нескольких столбцов/полей в подзапросе MySQL
В принципе, есть таблица атрибутов и таблица переводов - много переводов для одного атрибута.
Мне нужно выбрать id и значение из перевода для каждого атрибута на указанном языке, даже если на этом языке нет записи перевода. Либо я пропускаю какую-либо технику соединения, либо присоединяюсь (без использования языковой таблицы), здесь не работает, поскольку после этого не возвращаются атрибуты с не существующими переводами на указанном языке.
select a.attribute, at.id, at.translation
from attribute a left join attributeTranslation at on a.id=at.attribute
where al.language=1;
Итак, я использую подзапросы, подобные этому, проблема здесь заключается в создании двух подзапросов в одну и ту же таблицу с одинаковыми параметрами (это похоже на утечку производительности, если только mysql не группирует те, которые я сомневаюсь, поскольку он заставляет вас делать много подобных подзапросов)
select attribute,
(select id from attributeTranslation where attribute=a.id and language=1),
(select translation from attributeTranslation where attribute=a.id and language=1),
from attribute a;
Я хотел бы иметь возможность получать id и перевод из одного запроса, поэтому я concat столбцы и получить идентификатор из строки позже, что, по крайней мере, делает один подзапрос, но все еще не выглядит правильно.
select attribute,
(select concat(id,';',title)
from offerAttribute_language
where offerAttribute=a.id and _language=1
)
from offerAttribute a
Итак, часть вопроса.
Есть ли способ получить несколько столбцов из одного подзапроса или использовать два подзапроса (mysql достаточно умен, чтобы сгруппировать их?) Или присоединяется к следующему пути:
[[атрибут для языка] для перевода] (объединение трех таблиц выглядит хуже, чем подзапрос).
Ответы
Ответ 1
Да, вы можете это сделать. Вы должны знать, что есть два способа получить таблицы из сервера таблицы. Один из способов - это...
FROM TABLE A
Другим способом является
FROM (SELECT col as name1, col2 as name 2 FROM ...) B
Обратите внимание, что предложение select и круглые скобки вокруг него представляют собой таблицу, виртуальную таблицу.
Итак, используя ваш второй пример кода (я догадываюсь о столбцах, которые вы надеетесь получить здесь):
SELECT a.attr, b.id, b.trans, b.lang
FROM attribute a
JOIN (
SELECT at.id AS id, at.translation AS trans, at.language AS lang, a.attribute
FROM attributeTranslation at
) b ON (a.id = b.attribute AND b.lang = 1)
Обратите внимание, что ваша реальная таблица attribute
является первой таблицей в этом соединении и что эта виртуальная таблица, которую я назвал b
, является второй таблицей.
Этот метод особенно удобен, когда виртуальная таблица представляет собой сводную таблицу. например.
SELECT a.attr, b.id, b.trans, b.lang, c.langcount
FROM attribute a
JOIN (
SELECT at.id AS id, at.translation AS trans, at.language AS lang, at.attribute
FROM attributeTranslation at
) b ON (a.id = b.attribute AND b.lang = 1)
JOIN (
SELECT count(*) AS langcount, at.attribute
FROM attributeTranslation at
GROUP BY at.attribute
) c ON (a.id = c.attribute)
Посмотрите, как это происходит? Вы создали виртуальную таблицу c
, содержащую два столбца, присоединив их к двум другим, использовали один из столбцов для предложения ON
и вернули другое в качестве столбца в вашем результирующем наборе.