我试图从两列中减去查询结果。
表:
id | word1 | lang1 | word2 | lang2 |
----+-----------+-------+-----------+-------+
1 | car | 1 | car | 15 |
2 | table | 1 | table | 15 |
3 | Chair | 1 | cahair | 13 |
4 | CDplayer | 15 | CDplayer | 1 |
5 | car | 1 | car | 13 |
我想在语言1中将word1中的所有单词转换为未翻译成语言12.所以在这种情况下它将是主席
表中有300万行,以下查询需要1分钟才能运行:
SELECT DISTINCT word1
FROM `translations`
WHERE lang1 = 1
AND lang2 != 15
AND NOT IN (SELECT word1 FROM `translations` WHERE lang2 == 15)
LIMIT 10
分别对这两行进行选择是非常快的0.006s然后我可以在PHP中使用array_diff()
来相互减去它们,但可能有一种更简单的方法直接在MySQL中进行。
答案 0 :(得分:2)
SELECT
origin.word1
FROM
( SELECT DISTINCT word1
FROM tableX
WHERE lang1 = 1
) AS origin
WHERE
NOT EXISTS
( SELECT *
FROM tableX AS trans
WHERE trans.lang1 = 1
AND trans.lang2 = 15
AND trans.word1 = origin.word1
) ;
在运行这些查询之前,我会在(lang1, word1)
上添加一个索引,在(lang1, lang2, word1)
上添加索引。
你也可以尝试这种变化(并检查两个解释计划):
SELECT DISTINCT
word1
FROM
tableX AS origin
WHERE
lang1 = 1
AND
NOT EXISTS
( SELECT *
FROM tableX AS trans
WHERE trans.lang1 = 1
AND trans.lang2 = 15
AND trans.word1 = origin.word1
) ;
答案 1 :(得分:0)
这应该很简单
SELECT
m.id ,
l.*
FROM mytable m
INNER JOIN (
SELECT
*
FROM mytable
WHERE lang2 != 15
GROUP BY id
) as l ON l.id = m.id
WHERE l.lang1 = 1
GROUP BY m.id
答案 2 :(得分:0)
SELECT DISTINCT NonTranslated.word1
from
(SELECT DISTINCT word1 FROM `translations` WHERE lang1 = 1 AND lang2 != 15)NonTranslated
left join
(SELECT DISTINCT word1 FROM `translations` WHERE lang1 = 1 AND lang2 = 15)Translated
on NonTranslated.word1 = Translated.word1
where Translated.word1 is NULL;
让我知道这是什么解释。我认为它可能比选择子查询更快。
PS:假设:即使单词已翻译一次,也不会包含在列表中。
答案 3 :(得分:0)
我不确定我是否完全理解这个问题。聚合是否有效?
select word1
from translations t
group by word1
having max(lang1 = 1) = 1 and
max(lang2 = 15) = 0