【问题标题】:combining result of 5 sql queries by running a union and intersection通过运行联合和交集来组合 5 个 sql 查询的结果
【发布时间】:2012-11-30 13:44:43
【问题描述】:

我有 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 ;

但是如果任何查询为空,那么这将在 mysql 中产生错误。 一种方法是我构建 32 个条件(这将由这 5 个查询形成以检查不同的条件)

任何人都可以建议我另一种出路

我还需要对这 5 个查询的结果进行交集,而 sql 不支持 INTERSECT

请帮帮我

【问题讨论】:

  • 即使任何查询返回 null 也能正常工作
  • 它不是关于查询返回 null 如果联合在 2 个查询之间假设 query1 和 query2 则如果 query1 联合 query2 返回结果......现在如果 query2 如果为 null 则这是一个 sql 错误,在我的情况下,大约有 32 个这样的组合需要检查

标签: php mysql sql union intersect


【解决方案1】:

“查询为空”显然是指 PHP 变量为 null。这绝不是特定于 SQL 或 SQL 联合的。

重复ifs

所以你可以这样做:

$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 的结果。相应的代码可能如下所示(另见example on 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 中使用 joins。一个完整的示例可能如下所示:

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 thepkg_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 offoo IN (bar) `条件。然后你可以使用表名数组的第一个元素来扮演这个特殊的角色。

小心 SQL 注入

在将用户请求中的字符串粘贴到查询中时要小心。它们可能包含会破坏您的数据的丑陋的东西。确保输入是理智的,例如通过检查它是否只是一个以逗号分隔的整数值列表。或者use prepared statements,它可以让你远离这些问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2015-05-29
    • 2017-05-06
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 2019-12-04
    相关资源
    最近更新 更多