Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 嵌套选择查询优化_Sql - Fatal编程技术网

Sql 嵌套选择查询优化

Sql 嵌套选择查询优化,sql,Sql,我有一个表产品和一个表翻译。我对每个产品都有n翻译,但总是至少有一个默认翻译(LangID=0) 我要做的是对用户输入的字符串进行“搜索查询”。如果用户使用的语言有翻译(比如说LangID=1),我只想搜索该语言的翻译(也不想搜索默认语言),但如果没有所需语言的翻译,我想搜索默认翻译。因此,基本上默认的翻译只是一种退步 我想到的是: SELECT * FROM products p JOIN translations t ON p.ID = t.ProductID WHERE (t.LangI

我有一个表
产品
和一个表
翻译
。我对每个产品都有
n
翻译,但总是至少有一个默认翻译(
LangID=0

我要做的是对用户输入的字符串进行“搜索查询”。如果用户使用的语言有翻译(比如说
LangID=1
),我只想搜索该语言的翻译(也不想搜索默认语言),但如果没有所需语言的翻译,我想搜索默认翻译。因此,基本上默认的翻译只是一种退步

我想到的是:

SELECT * FROM products p JOIN translations t ON p.ID = t.ProductID 
WHERE (t.LangID = 1 OR (t.LangID = 0 AND NOT EXISTS (SELECT id FROM translations t2 WHERE t2.ProductID = p.ID AND t2.LangID = 1))
      AND t.Translation LIKE "Foo%" `

这是最好的方法还是不使用嵌套的select就可以做到这一点?或者有更好的(性能方面的)查询/方法吗?

您可以这样做,但不清楚执行计划是好是坏。
的组合存在
不能可靠地产生一个好的计划

只需加入两次即可更安全、更快:

select *
from products p
left join translations t1 on t1.langid = 1 and ...
left join translations t0 on t1.langid is null and t0.langid = 0 and ...
然后使用
t1
的值(如果存在)。如果不是,则使用
t0
的值。谓词
t1.langid为null
是可选的,但是如果第一个连接成功,它允许SQL Server(希望如此)跳过第二个连接。我见过这种模式起作用,但假设它总是起作用是不安全的

这将产生一个可靠且简单的计划

with t as (
SELECT * FROM products p JOIN translations t ON p.ID = t.ProductID 
WHERE t.LangID = 1 AND t.Translation LIKE "Foo%")
select * from t
union all
SELECT * FROM products p, translations t 
 where (select count(*) from t) = 0
   and p.ID = t.ProductID 
   and t.LangID = 0 AND t.Translation LIKE "Foo%"';
这是一种Oracle语法,t只是一个子查询(使用可以为子查询命名)

如果计算t的过程很复杂,则此查询可能会更快


另外,您的数据库可能不会对WHERE条件使用捷径评估。需要测试(实际上Oracle不保证它的使用,但Oracle optimizer足够智能,所以它在我的情况下工作)

谢谢这是对我最好的答案。我编写的完整查询:
select p.Id,COALESCE(t1.Translation,t0.Translation)从产品p左连接翻译t1到t1.ProductId=p.Id,t1.LanguageId=1左连接翻译t0到t0.ProductId=p.Id,t1.LanguageId=0,其中t1.Translation像'Foo%'或t0.Translation像'Foo%