在 MySQL 子查询中选择多个列/字段
Posted
技术标签:
【中文标题】在 MySQL 子查询中选择多个列/字段【英文标题】:Selecting multiple columns/fields in MySQL subquery 【发布时间】:2011-04-16 11:52:54 【问题描述】:基本上,有一个属性表和翻译表——一个属性有很多翻译。
我需要为指定语言的每个属性从翻译中选择 id 和 value,即使该语言没有翻译记录。要么我错过了一些连接技术,要么连接(不涉及语言表)在这里不起作用,因为以下不返回指定语言中不存在翻译的属性。
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 和翻译,因此我连接列并稍后从字符串中获取 id,这至少是在进行单个子查询但仍然看起来不正确。
select attribute,
(select concat(id,';',title)
from offerAttribute_language
where offerAttribute=a.id and _language=1
)
from offerAttribute a
所以问题部分。 有没有办法从单个子查询中获取多个列,或者我应该使用两个子查询(MySQL 足够聪明,可以将它们分组?)或者加入以下方式:
[[attribute to language] to translation](加入 3 个表的性能似乎比子查询差)。
【问题讨论】:
【参考方案1】:是的,您可以这样做。您需要的诀窍是有两种方法可以从表服务器中获取表。一种方法是..
FROM TABLE A
另一种方法是
FROM (SELECT col as name1, col2 as name2 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
子句,并将另一列作为结果集中的一列返回。
【讨论】:
SELECT a.attribute, b.id, b.translation FROM attribute a left JOIN (SELECT id, translation, attribute FROM translation where _language=1) b on a.id=b.attribute 是什么我为我工作,谢谢:) @Martin,你可以加入;不需要虚拟表。 SELECT a.a, tr.id, tr.translation FROM attribute a LEFT JOIN translation tr ON a.id=tr.attribute WHERE tr.language=1 我提到,可能没有足够指出,有些记录没有翻译,所以如果我说语言=1并且没有翻译,我错过了属性记录。 @O.Jones - 这会起作用,但如果 attributeTranslation 表很大,它可能比 OP 问题中使用的子查询效率低很多,因为虚拟表不能从attribute_id 索引(假设有一个)。我很想知道是否有办法实现构建虚拟表但按表 a 中的列限制它。到目前为止,我一直坚持使用 OP 的方法以上是关于在 MySQL 子查询中选择多个列/字段的主要内容,如果未能解决你的问题,请参考以下文章