PHP选择多个数组表

时间:2016-03-22 17:33:54

标签: php mysql arrays select

是否可以SELECT使用多个数组表。我知道这听起来令人困惑,但这就是我所做的:

首先,我创建了一个表单,它有两个复选框选项,如下所示:

<form action="something.php" method="post">
<input type="checkbox" name="store[]" value="M1">
<input type="checkbox" name="store[]" value="M2">
<input type="submit" value="Go">
</form>

现在提交表单后,我可以查看通过foreach loop选择的商店:

$allstore = $_POST['store'];
 foreach ($allstore as $store=>$value) {
echo $value;
}

到目前为止,一切都按需要运作! 但是,复选框中的这两个值被视为表名!现在,我如何找到一种方法让PHP根据用户选择$value选择一个或两个表?

$query = "SELECT * from **{$allstore[0]},{$allstore[1]}** WHERE .....";

如您所见 {$ allstore [0]},应根据foreach循环创建{$ allstore [1]} 。我似乎无法找到一种方法!我可以插入一个函数来为我做吗?

像这样:$query = "SELECT * from ((( Function Here ))) WHERE .....";

如果你有不同的做法,请分享。

编辑:

M1表

id |item_no |qty |price
1   x1       10   20
2   x2       5    22
3   x3       3    5

M2表

id |item_no |qty |price
1   x1      11    20
2   x9      5     30
3   x10     6     26

输出表应为

item_no | price |   M1 |  M2
x1         20       10    11
x2         22       5     N/A
x3         5        3     N/A
x9         30       N/A   5
x10        26       N/A   6

这就是我的目标。我希望它可以解决!

2 个答案:

答案 0 :(得分:1)

这是2个表sqlfiddle的结构 我想你可以从这里添加更多表格。

SELECT T1.item_no,
  COALESCE(M1.price,M2.price) as price,
  M1.qty as M1,
  M2.qty as M2
FROM
  (SELECT item_no FROM M1
    UNION
   SELECT item_no FROM M2
   )T1
   LEFT JOIN M1 ON T1.item_no = M1.item_no
   LEFT JOIN M2 ON T1.item_no = M2.item_no

更新:我对PHP不太熟悉,但我查了一些语法,能够根据[“M1”,“M2”]或[“M1”]或[“M2”的数组动态生成SQL ]

DynamicPHPtobuildSQL

<?php
        //Enter your code here, enjoy!

$allstore = ["M2"];
$item = 0;
$sqlpart1 = "";
$sqlpart2 = "";
$sqlpart3 = "";
$sqlpart4 = "";
foreach ($allstore as $store=>$value) {
   $item += 1;
   if ($item > 1){
     $sqlpart1 .= ",";
     $sqlpart2 .= ",";
     $sqlpart3 .= " UNION ";
   }
   $sqlpart1 .= $value . ".price ";
   $sqlpart2 .= $value . ".qty as " . $value . " ";
   $sqlpart3 .= "SELECT item_no FROM " . $value . " ";
   $sqlpart4 .= "LEFT JOIN " . $value . " ON T1.item_no=" . $value . ".item_no ";
}
$SQL = "SELECT T1.item_no,COALESCE(" . $sqlpart1 . ") as price," . $sqlpart2;
$SQL .= "FROM (" . $sqlpart3 . ")T1 " . $sqlpart4;
echo $SQL;
?>

答案 1 :(得分:0)

小心避免SQL injection的风险:将已过帐的值与现有商店表名的已关闭列表进行比较,并拒绝任何其他值。

另请注意,FROM子句不仅受用户选择的影响,还受SELECT子句的影响。因此,在SQL语句中有两个动态部分。

您可以使用此代码,该代码使用array_intersectimplodearray_map

$selected_stores = $_POST['store'];

// Protect against SQL-injection by only accepting known tables:
$all_stores = array("M1", "M2", "M3");
$selected_stores = array_intersect($selected_stores, $all_stores);

// Build dynamic part of the FROM clause
$from = implode("
           UNION
           ", array_map(function ($store) { 
    return "SELECT '$store' as store, item_no, price, qty FROM $store";
}, $selected_stores));

// Build dynamic part of the SELECT clause
$cols = implode(",
     ", array_map(function ($store) { 
    return "CASE store WHEN '$store' THEN qty END AS $store";
}, $selected_stores));

$sql = "
SELECT   item_no,
         MAX(price) as price,
         $cols
FROM     ( $from ) data
GROUP BY item_no
";

生成的SQL如下所示:

SELECT   item_no,
         MAX(price) as price,
         CASE store WHEN 'M1' THEN qty END AS M1,
         CASE store WHEN 'M2' THEN qty END AS M2
FROM     ( SELECT 'M1' as store, item_no, price, qty FROM M1
           UNION
           SELECT 'M2' as store, item_no, price, qty FROM M2 ) data
GROUP BY item_no

另见this SQL fiddle

作为旁注:我建议将所有商店表合并到一个表中,这将有一个表示商店的附加列。这更符合规范化的数据库设计,并且在搜索,排序,性能和简单性方面将提供比缺点更多的优势。