Mysql 将已联接的表联接到自身

Mysql 将已联接的表联接到自身,mysql,join,Mysql,Join,我有一个数据库表dictionary,它有两个字符串和一个语言id 各栏分别为: id product_id key translation language_id 另一个表dictionary\u versions只包含dictionary\u id和翻译版本 id dictionary_id version_id 表中每个键有两个不同的翻译,但有时,只有一个键的翻译。我正在寻找一种方法来获得一种语言的所有翻译,如果有的话,还有另一种语言id的翻译 我希望得到一种语言和组织者id和一个版本

我有一个数据库表dictionary,它有两个字符串和一个语言id

各栏分别为:

id
product_id
key
translation
language_id
另一个表dictionary\u versions只包含dictionary\u id和翻译版本

id
dictionary_id
version_id
表中每个键有两个不同的翻译,但有时,只有一个键的翻译。我正在寻找一种方法来获得一种语言的所有翻译,如果有的话,还有另一种语言id的翻译

我希望得到一种语言和组织者id和一个版本的所有翻译。我尝试创建一个临时表,其中包含我要比较的所有值,然后在字典表上对临时表进行左连接,以获得所需语言的所有翻译值,如果有其他语言的翻译,则包括这些翻译

问题是,当两种语言有10000个翻译时,速度会变慢。是否有更好的方法将dictionary\u versions表作为where子句连接到表本身

SELECT
    d.*
FROM
    dictionary d 
LEFT JOIN
    dictionary_versions dv ON dv.dictionary_id = d.id
LEFT JOIN
    dictionary d2
LEFT JOIN
    dictionary_versions dv2 ON d2.id = dv2.dictionary_id
ON
    d2.key = d.key 
WHERE
    d.product_id = 1 AND dv.version_id = 3
AND
    d.language_id = 1
LIMIT
    0,10 
这是我尝试的问题之一。但是,如果有多个版本,则会获取fd2表的所有版本,从而导致数据不准确

我尝试的另一种方法是使用临时桌子,这很有效,但速度很慢。它通过两个查询完成:

CREATE TEMPORARY TABLE IF NOT EXISTS dictionary_temp_1 
AS (
    SELECT d.* FROM `dictionary` AS `d`
    LEFT JOIN `dictionary_versions` AS `dv` ON dv.dictionary_id = d.id
    WHERE d.product_id = 1 AND dv.version_id = 3 AND d.language_id = 1 
    ORDER BY fd.key ASC LIMIT 0,10 )
第二:

SELECT
    d.key,
    d2.key AS toKey,
    d.translation AS `1`,
    d2.translation AS `2`
FROM
    `dictionary` AS `d`
LEFT JOIN
    `dictionary_versions` AS `dv` ON d.id = dv.dictionary_id
LEFT JOIN
    `dictionary_temp_1` AS `d2` ON d2.key = d.key
WHERE
     d.product_id = 1 AND dv.version_id = 3 AND d.language_id = 1
ORDER BY
     d.key ASC LIMIT 0,10

感谢@philipxy,我设法找到了一个解决方案,将此作为参考,并将其指向我作为参考

SELECT d.key, d2.key AS toKey, d.translation AS `1`, d2.translation AS `2`
FROM dictionary d 
INNER JOIN dictionary_versions dv ON dv.dictionary_id = d.id 
LEFT JOIN (
    SELECT d.* 
    FROM `dictionary` AS `d`
    INNER JOIN `dictionary_versions` AS `dv` ON d.id = dv.dictionary_id 
    WHERE d.product_id = 1 AND dv.version_id = 3 AND d.language_id = 2
) d2 ON d2.key = d.key 
WHERE d.product_id = 1 AND dv.version_id = 3 AND d.language_id = 1 

这将在将子查询连接到表本身之前创建子查询。where条件应用于两个表,因此获取一种语言\u id的翻译,并匹配不同语言\u id的任何翻译(如果存在)。

将您的代码添加到问题中。请注意,键是保留字,因此表/列标识的选择很差一组样本行,另外,预期结果既能说明您的意思,又能让我们演示解决方案。另外,它实际上有助于查看您已经尝试过的代码。如果你做这些事情而不是回答问题,你可能在测试提议的解决方案。。。。使用SQL保留字或关键字命名任何对象都是不好的做法,它最终会困扰你。这很有帮助!但是样本数据呢?问题是,你已经有了,而我们没有。只有几行被复制/粘贴成问题。如果需要,您可以在此处形成ascii表。对于性能相关的问题,应该始终查看<代码>解释计划< /代码>,并考虑查询是否使用索引。你这样做了吗?那些表上有什么索引?真高兴。但是第一个&嵌套的左撇子应该是内部的,以免误导。如果你认为他们一定是左撇子,那你就错了。正如我已经说过的,@philipxy你是对的,他们应该是内在的。where条件涵盖了左派会做什么,我想你知道我在说什么,但是你的评论措辞不明确,没有说什么,它只是帮助我们猜测你的意思。如果你强迫自己用足够的单词、短语和句子清楚地表达事物,那么你就能更有效地理解、推理、交流和编码。