我有5个查询,如下所示,我需要对所有执行并集
if($dv_state_ids!="")//check if no state is entered
$state_sql="SELECT pkg_id FROM package_state where state_id in ($dv_state_ids) ";
if($dv_city_ids!="")//check if no city is entered
$city_sql="SELECT pkg_id FROM package_city where city_id in ($dv_city_ids)";
if($dv_category_ids!="")//check if nocategory is entered
$category_sql="SELECT pkg_id FROM package_category where category_id in ($dv_category_ids) ";
if($dv_sub_category_ids!="")//check if no subcategory is found
$sub_category_sql="SELECT pkg_id FROM package_category where subcategory_id in ($dv_sub_category_ids) ";
if($dv_category_ids!="")
$package_sql="SELECT pkg_id FROM package where id in ($dv_category_ids) ";
我可以通过以下语句对上述查询运行联合
$sql_get_any_packages=$state_sql." union ".$city_sql."
union
".$category_sql." union ".$sub_category_sql." union ".$package_sql ;
但是如果任何查询为null,那么这将在mysql中生成一个错误。一种方法是,i帧32个条件(将由这5个查询形成,以检查不同的条件)
有人能建议我另一条出路吗
我还需要对这5个查询的结果执行交集,并且sql不支持INTERSECT
请帮我处理这个
"查询为空"显然是指PHP变量为null
。这绝不是SQL或SQL联合所特有的。
重复if
s
所以你可以做的是:
$sql_get_any_packages = "";
if (!is_null($state_sql))
$sql_get_any_packages .= " union " . $state_sql;
if (!is_null($city_sql))
$sql_get_any_packages .= " union " . $city_sql;
if (!is_null($category_sql))
$sql_get_any_packages .= " union " . $category_sql;
if (!is_null($sub_category_sql))
$sql_get_any_packages .= " union " . $sub_category_sql;
if (!is_null($package_sql))
$sql_get_any_packages .= " union " . $package_sql;
$sql_get_any_packages = substr($sql_get_any_packages, strlen(" union "));
这只需收集所有非null
部分,包括每个部分的前导" union "
,并在末尾删除初始" union "
。如果所有查询可能同时是null
,那么最终结果将是FALSE
。
使用数组
作为一种替代方案,您可以将零件放入一个数组中,使用array_filter
放置null
元素,然后使用" union "
作为胶水放置implode
结果。相应的代码可能看起来像这样(另请参阅ideone上的示例):
$sql_get_any_packages = array(
$state_sql,
$city_sql,
$category_sql,
$sub_category_sql,
$package_sql);
$sql_get_any_packages = array_filter($sql_get_any_packages);
$sql_get_any_packages = implode(" union ", $sql_get_any_packages);
关于相交
如果要与结果相交,则不希望合并它们的并集。一旦你建立了一个联盟,你就无法再访问它的各个部分,所以你无法将它们相互比较。要实现交集,可以在SQL中使用联接。完整的例子可能是这样的:
SELECT package_state.pkg_id
FROM package_state, package_city, package_category, package_category, package
WHERE package_state.state_id IN ($dv_state_ids)
AND package_city.city_id IN ($dv_city_ids)
AND package_category.category_id IN ($dv_category_ids)
AND package_category.subcategory_id IN ($dv_sub_category_ids)
AND package.id in ($dv_category_ids)
AND package_state.pkg_id == package_city.pkg_id
AND package_state.pkg_id == package_category.pkg_id
AND package_state.pkg_id == package.pkg_id
您可以使用类似于我上面描述的解决方案来构建这样的查询,但它们会变得稍微复杂一些。特别是,上面查询中的表package_state
扮演的角色与所有其他表有些不同:这是SELECT
输出值的表形式,以及s also the table which occurs on the left hand side of all the
pkg_idcomparisons, where the other tables appear on the right hand side. So you might want to collect several arrays, one of table names and one of
foo In(bar)`条件。然后,您可以使用表名数组的第一个元素来扮演这个特殊的角色。
小心SQL注入
在将用户请求中的字符串粘贴到查询中时要小心。它们可能包含丑陋的东西,会破坏你的数据。确保输入是合理的,例如检查它是否只是一个逗号分隔的整数值列表。或者使用预先准备好的语句,这样可以将您与大多数这些问题隔离开来。