我有一个查询,根据不同的ID获取结果,我的查询看起来像这样:我已经缩短了查询,仍然,还有两个WHERE In条件.
SELECT DISTINCT restaurant.*,branch.*
from restaurant,branch,restaurant_cuisines,restaurant_collections
WHERE restaurant.restaurant_id=branch.restaurant_id
AND restaurant_cuisines.cuisine_id IN (2,3)
AND restaurant_collections.collection_id IN ();
Run Code Online (Sandbox Code Playgroud)
如果条件中的第二个WHERE中没有值,如何执行此查询?或者如何在应用程序级别(Java)中处理这个问题,我需要编写大约28个if if条件来检查空条件.怎么克服这个?
这一切都取决于您的需求.通常你应该跳过整个部分.
当你使用AND所有条件时,我假设你想通过空列表返回所有行.(我猜最终用户有一些多个复选框或类似的东西).
如果定义了列,NOT NULL您可以在JAVA中生成代码,如下所示:
...
AND restaurant_collections.collection_id IN(restaurant_collections.collection_id)
-- which is always true and good query optimizer should skip entire part
Run Code Online (Sandbox Code Playgroud)
当您需要特定值时,可以像以前一样使用它:
...
AND restaurant_collections.collection_id IN (1,2,3)
Run Code Online (Sandbox Code Playgroud)
如果您想要的只是查询正常工作,您应该能够使用:
SELECT DISTINCT restaurant.*,branch.*
from restaurant,branch,restaurant_cuisines,restaurant_collections
WHERE restaurant.restaurant_id=branch.restaurant_id
AND restaurant_cuisines.cuisine_id IN (2,3)
AND restaurant_collections.collection_id IN (NULL);
Run Code Online (Sandbox Code Playgroud)
但这始终不会返回任何结果。
如果您想要更灵活的东西,或者如果您希望collection_id没有任何值传递给它的所有结果,我建议从隐式连接更改为显式连接。
现在您正在使用隐式连接语法:
SELECT A.*, B.*, C.* FROM A,B,C
WHERE A.j=B.j AND A.j=C.j
Run Code Online (Sandbox Code Playgroud)
这样做的问题是,如果C.j为空,即使您修复语法,查询也不会返回任何内容。
显式连接允许采用更细致的方法:
SELECT A.*, B.*, C.* FROM A
INNER JOIN B ON A.j=B.j AND B.v IN (1,2)
LEFT JOIN C ON A.j=C.j AND C.v IN (NULL);
Run Code Online (Sandbox Code Playgroud)
当您编码时,不要传递空字符串,而是传递 null 值(或者,如果您不使用准备好的语句,则传递包含 的字符串NULL)。否则,将值作为列表传递。
如果您需要仅在没有值时忽略行,则可以执行以下操作:
SELECT A.*, B.*, C.* FROM A
INNER JOIN B ON A.j=B.j AND B.v IN (1,2)
LEFT JOIN C ON A.j=C.j
WHERE (COALESCE(<val>) IS NULL OR C.v IN (<val>));
Run Code Online (Sandbox Code Playgroud)
当您添加 theLEFT JOIN然后在子句中引用它时,您可以使用COALESCEWHERE函数轻松检查 the 是否包含值列表以及传递的值是否不为空。C.v
总之,LEFT连接非常灵活,允许您稍后返回并可选择强制执行严格的INNER JOIN. 它们不应该在INNER JOIN完成工作时使用,但绝对有它们的用途,例如这里。
LEFT关于vs 的注释INNER:
LEFT JOIN。INNER JOIN。