我在组合MySQL查询时遇到了一些问题。它是多语言,多目标站点的一部分,因此我需要从多个表中检索站点的一些文本部分,并使用回退。可能命中的顺序:
更正@ local_tbl> english @ local_tbl>更正@ global_tbl> 英语@ global_tbl。
因为它会被高度使用,所以我希望保持快速且连接数少,但只返回1行。我尝试了以下几种方法,但我确信有更好的解决方案。
FROM子句中的子查询:如果任何子查询给出0行,它就会死掉。即使它有效,也需要一些PHP解释:
SELECT * FROM
(SELECT `sp_content` AS sp_local FROM `loc-ae_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'de' AND `sp_corrected`='1' LIMIT 1) as local,
(SELECT `sp_content` AS sp_local_en FROM `loc-ae_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'en' LIMIT 1) as local_en,
(SELECT `sp_content` AS sp_global, `sp_corrected` as sp_global_corrected FROM `loc-global_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'de' LIMIT 1) as global,
(SELECT `sp_content` AS sp_global_en FROM `loc-global_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'en' LIMIT 1) as global_en
TEMP表:这里我关注性能,不能使用内存引擎,因为它涉及文本字段。小鸟的核武器?
CREATE TEMPORARY TABLE IF NOT EXISTS `random_tbl_name` AS (SELECT `sp_content` FROM `loc-global_siteparts` LIMIT 0);
INSERT INTO `random_tbl_name` SELECT `sp_content` FROM `loc-ae_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'de' AND `sp_corrected` = '1' LIMIT 1;
INSERT INTO `random_tbl_name` SELECT `sp_content` FROM `loc-ae_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'en' LIMIT 1;
INSERT INTO `random_tbl_name` SELECT `sp_content` FROM `loc-global_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'de' AND `sp_corrected` = '1' LIMIT 1;
INSERT INTO `random_tbl_name` SELECT `sp_content` FROM `loc-global_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'en' LIMIT 1;
SELECT * FROM `random_tbl_name` LIMIT 1;
编辑:感谢所有答案,他们真的很有帮助。
答案 0 :(得分:1)
SELECT * FROM
((SELECT 1 precedence, `sp_content`
FROM `loc-ae_siteparts`
WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'de' AND `sp_corrected`='1'
LIMIT 1)
UNION
(SELECT 2 precedence, `sp_content`
FROM `loc-ae_siteparts`
WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'en'
LIMIT 1)
UNION
...
) x
ORDER BY precedence
LIMIT 1
答案 1 :(得分:0)
当其中一个子查询为空时没有结果的原因是
select * from
s1, s2, s3, s4
你有一个隐含的联接。当其中一个子结果为空时,结果连接也是空的。
要解决此问题,您可以将子查询用作列。这将给出相同的结果,但是使用NULL值,其中subselect不返回任何行
SELECT (SELECT `sp_content` AS sp_local FROM `loc-ae_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'de' AND `sp_corrected`='1' LIMIT 1) as local,
(SELECT `sp_content` AS sp_local_en FROM `loc-ae_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'en' LIMIT 1) as local_en,
(SELECT `sp_content` AS sp_global, `sp_corrected` as sp_global_corrected FROM `loc-global_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'de' LIMIT 1) as global,
(SELECT `sp_content` AS sp_global_en FROM `loc-global_siteparts` WHERE `sp_name` = 'name_of_some_sitepart' AND `sp_lang` = 'en' LIMIT 1) as global_en
答案 2 :(得分:0)
我过去做过类似的事情:
SELECT COALESCE(ls1.sp_content, ls2.sp_content) AS sp_content
FROM (SELECT 1) a
LEFT JOIN loc-ae_siteparts ls1
ON ls1.sp_name = 'name_of_some_sitepart' AND ls1.sp_lang = 'de' AND ls1.sp_corrected = '1'
LEFT JOIN loc-ae_siteparts ls2
ON ls2.sp_name = 'name_of_some_sitepart' and ls2.sp_lang = 'en'
LIMIT 1