我有一个很大的MySQL语句,通过php foreach循环,并且每个循环都通过union all连接到先前的循环。我会将语句简化为问题的核心,如果需要的话,我当然也可以在以后根据要求添加更多详细信息。
我有这张桌子
+--------+-----------+-----------+ | ID | LANG | TITLE | +--------+-----------+-----------+ | 1 | EN | T-A | +--------+-----------+-----------+ | 1 | FR | T-A | +--------+-----------+-----------+ | 2 | FR | T-B | +--------+-----------+-----------+ | 3 | DE | T-C | +--------+-----------+-----------+ | 3 | EN | T-C | +--------+-----------+-----------+
我想在SQL SELECT中写一个 WHERE 条件,该条件应显示 每个ID最多一个结果 。但是, 仅当LANG为FR或EN时, 它才应显示结果。最重要的是, 应该优先使用FR, 并且仅当ID没有可用的FR时,才应显示EN作为替代。因此结果将如下所示。
+--------+-----------+-----------+ | ID | LANG | TITLE | +--------+-----------+-----------+ | 1 | FR | T-A | +--------+-----------+-----------+ | 2 | FR | T-B | +--------+-----------+-----------+ | 3 | EN | T-C | +--------+-----------+-----------+
我曾尝试使用IF-ELSE / CASE自己构建一些东西,但是我对SQL的经验不是很丰富,因此将不胜感激。
我尝试过的简化SQL就像
SELECT * FROM `table` WHERE `table`.`ID` = 1 IF `table`.`LANG` = 'FR' BEGIN AND `table`.`LANG` = 'FR' END ELSE BEGIN AND `table`.`LANG` = 'EN' END union all SELECT * FROM `table` WHERE `table`.`ID` = 2 IF `table`.`LANG` = 'FR' BEGIN AND `table`.`LANG` = 'FR' END ELSE BEGIN AND `table`.`LANG` = 'EN' END union all SELECT * FROM `table` WHERE `table`.`ID` = 3 IF `table`.`LANG` = 'FR' BEGIN AND `table`.`LANG` = 'FR' END ELSE BEGIN AND `table`.`LANG` = 'EN' END
网站说明我可能无法将ORDER BY与LIMIT 1结合使用任何构造,因为我每次循环都要通过php将SQL循环多次。
编辑: 对我 有用的 解决方案
SELECT * FROM `table1` WHERE ID = 1 AND lang = 'FR' OR (lang = 'EN' AND ID NOT IN (SELECT ID FROM table1 WHERE lang = 'FR'))
使用复杂的查询优化器的最优雅,最有效的解决方案是:
SELECT * FROM ( SELECT * FROM `table` WHERE ID IN ( SELECT id FROM `table` WHERE lang = 'EN' EXCEPT SELECT id FROM `table` WHERE lang = 'FR' ) OR table.LANG ='FR' ) t1 WHERE id = ?
这将为您提供所需的结果,并按ID过滤。但是,如果优化器无法降低性能,则id = ?您可能必须自己进行操作才能获得不错的性能:
id = ?
SELECT * FROM `table` WHERE id = ? AND (ID IN ( SELECT id FROM `table` WHERE lang = 'EN' AND ID = ? EXCEPT SELECT id FROM `table` WHERE lang = 'FR' AND ID = ? ) OR table.LANG ='FR')
但是,如果可以的话,我将立即获得所有结果,而不是首先遍历ID:
SELECT * FROM `table` WHERE ID IN ( SELECT id FROM `table` WHERE lang = 'EN' EXCEPT SELECT id FROM `table` WHERE lang = 'FR' ) OR table.LANG ='FR'
这将为您提供所有带有lang’EN’且没有相应的’FR’以及所有’FR’的ID。另外,您也可以尝试:
SELECT * FROM `table` WHERE lang = 'FR' OR (lang = 'EN' AND ID NOT IN (SELECT ID FROM table WHERE lang = 'FR'))
或者
SELECT * FROM `table` WHERE lang = 'FR' OR (table.LANG = 'EN' AND NOT EXISTS (SELECT * FROM table t1 WHERE lang = 'FR' AND t1.id = table.id))
但是我的猜测是第一个查询最快。