0

我有一个 MySQL 表,其中包含客户可以订购的所有可能产品的列表。该表的(非常)简化版本如下所示:

ID  |  productid    |    price    |   age_min   |   age_max   |   type
=======================================================================
1   |   baseball_1  |    12.34    |    18       |    21       |    1
2   |   baseball_2  |    15.99    |    22       |    30       |    1
3   |   baseball_3  |    18.99    |    18       |    99       |    1
4   |   golf_1      |    4.99     |    18       |    24       |    2
5   |   golf_2      |    5.99     |    25       |    44       |    2
6   |   tennis_1    |    9.99     |    18       |    50       |    3
7   |   tennis_2    |    14.99    |    51       |    99       |    3

在这家商店,所有产品都有年龄限制,这意味着客户只有在他/她的年龄符合该范围的情况下才能选择要购买的商品。即使每个产品“类型”存在多个选项,定制也只能选择一种“类型”。在上面的示例表中,24 岁的客户只能选择:

棒球_2、棒球_3 高尔夫_1 和网球_1

我正在尝试按已知产品类型组织潜在客户的选项。因此,就我而言,商店可能会向客户展示:

棒球选项

  • 棒球_2 - 15.99 美元
  • 棒球 3 - 18.99 美元

高尔夫选项

  • Golf_1 - 4.99 美元

网球选项

  • 网球_1 - 9.99 美元

我想使用 age 变量对数据库进行一次(如果可能)MySQL 调用,并返回所有可能的产品,然后如上所述相应地显示这些产品。SQL 语句很简单,我已经完成了这项工作,但我不确定如何循环或构建一个适当的数组,该数组可以列出成员的可用选项。

可能会提出建议,但这比显示的要详细得多,并且由于与该问题无关的其他几个因素,因此不能选择使用任何类型的第三方软件或购物车。看来这是如何处理多维数组的问题。以前有人遇到过类似的问题吗?


更新

虽然 Travesty 和 tdammer 下面提供的解决方案在某些情况下是有效的,但我希望能够对我的数据做更多的事情,然后将其从我的数据库中显示出来。页面的布局和设计不应取决于它在数据库中的存储方式/时间/等。有时我想先显示一组“类型”的最高价格,而先显示另一组“类型”的最低价格。

通过使用 fetchAll 语句,我能够从查询中收集我需要的所有必要数据,但我真的不确定如何使用它。例如,我的数组当前是:

Array (
    [0] => Array ( [productid] => 394, [price] => 6.20,  [type] => 16 ),
    [1] => Array ( [productid] => 395, [price] => 12.40, [type] => 16 ),
    [2] => Array ( [productid] => 396, [price] => 18.60, [type] => 16 ),
    [3] => Array ( [productid] => 397, [price] => 24.80, [type] => 16 ),
    [4] => Array ( [productid] => 398, [price] => 31.00, [type] => 16 ),
    [5] => Array ( [productid] => 449, [price] => 4.20,  [type] => 17 ),
    [6] => Array ( [productid] => 450, [price] => 8.40,  [type] => 17 ),
    [7] => Array ( [productid] => 451, [price] => 12.60, [type] => 17 ),
    [8] => Array ( [productid] => 452, [price] => 16.80, [type] => 17 ),
    [9] => Array ( [productid] => 453, [price] => 21.00, [type] => 17 )
)

有没有一种好方法来构建我自己的数组,我以后基本上可以说“向我展示所有类型为 17 的项目的产品 ID 和价格”?

4

3 回答 3

3

为此,您不需要多维数组。

只需按类型对查询结果进行排序,然后在数组中循环。这样做时,在第一个项目之前插入一个标题,然后在类型更改的每个项目之前插入一个标题。

如果您有一个适当规范化的数据库,您还应该有一个product_types包含产品类型 ID 和名称的表;在这种情况下,考虑一个JOIN. 然后你的 SQL 看起来有点像这样:

SELECT p.id, p.name, p.price, t.id AS type_id, t.name AS type_name FROM products AS p LEFT JOIN product_types t ON t.id = p.type WHERE :age BETWEEN p.min_age AND p.max_age;

然后,您逐步检查结果集,如下所示:

$current_type = 'not_a_string';
while ($row = get_next_row_from_database) {
    if ($current_type !== $row['type_id']) {
        echo '<h3>' . htmlspecialchars($row['type_name']) . '</h3>';
        $current_type = $row['type_id'];
    }
    printf('<p>%s - $%2.2f</p>', htmlspecialchars($row['name']), $row['price']);
}

这种方法使用恒定内存(在 Web 服务器上,显然不在数据库上)和线性时间。

您还应该考虑数据的分页:不要一次查询所有行,而是运行COUNT(*)查询以获取总行数,然后用于LIMIT仅获取当前页面的行(您可能还想指定一个ORDER BY子句以使您的页面有意义)。

于 2012-05-08T19:02:17.967 回答
3

我认为您不需要为此使用多维数组。我认为当你来到一个新组时,你只需要遍历你的行并更改你的标题。

我对这个答案使用了一些不同的方法,将每一行粘贴到一个数组中,然后将它们内爆,以便保留格式。

//USING PDO - assume connection already made
/* added ORDER BY in the query to ensure that we get the rows sequentially, by type */
$stmt = $db->prepare("SELECT * FROM table WHERE age_min >= :age AND age_max <= :age ORDER BY type");
$stmt->bindParam(":age", $customer_age);
$stmt->execute();

$type = -1;
$lines = array();
while ($data = $stmt->fetch(PDO::FETCH_ASSOC))
{
    $data = array_map("htmlspecialchars", $data); /* sanitize data for HTML output */

    if ($type != $data["type"])
    {
        $type = $data["type"];
        list($typeName) = explode("_", $data["productid"]); /* this assumes that you don't have a column with the actual product name. If you do, use that instead. */
        $lines[] = (count($lines) > 0 ? "</ul>\n" : "") ."<h2>". ucfirst($typeName) ." Option</h2>\n<ul>";
    }

    $lines[] = "\t<li>{$data["productid"]} - {$data["price"]}</li>";
}

echo implode("\n", $lines) ."\n</ul>";


对问题更新的回应:

有没有一种好方法来构建我自己的数组,我以后基本上可以说“向我展示所有类型为 17 的商品的产品 ID 和价格”?

那是一个查询。我仍然认为没有理由将其存储在数组中。如果您想获取类型为 17 的所有商品的 productid 和 price,那么您应该在数据库上执行该查询。如果您想以不同的方式对结果进行排序,那么您应该更改您的ORDER BY子句。

也许您需要调整您的查询,使其更加灵活:

if (!isset($_POST["columns"]))
    $_POST["columns"] = "productid, price";
if (!isset($_POST["whereClause"]))
    $_POST["whereClause"] = "TRUE";
if (!isset($_POST["orderby"]))
    $_POST["orderby"] = "type ASC, price DESC";

$stmt = $db->prepare("SELECT :columns FROM table WHERE age_min >= :age AND age_max <= :age AND :whereClause ORDER BY :orderby");
$stmt->bindParam(":columns", $_POST["columns"]);
$stmt->bindParam(":age", $customer_age);
$stmt->bindParam(":whereClause", $_POST["whereClause"]);
$stmt->bindParam(":orderby", $_POST["orderby"]);
$stmt->execute();

您可以使用 HTML 表单提交(导致页面重新加载)调用它,也可以通过 AJAX 调用它。但无论哪种方式,我都看不出做 afetchAll并将结果存储在数组中对你有什么好处。

于 2012-05-08T19:10:57.593 回答
1

根据数据库的大小,此解决方案可能不起作用,但通常我在较小规模上的工作方式是:

将数据库结果循环到我的设计数组中

所以我可能有

Array['baseball'][0]['price'] = 15.99
Array['baseball'][1]['price'] = 18.99

循环遍历我创建的数组以解析结果。

在更大的数据库中,您将需要不同的解决方案,因为这会使您多次循环结果结果......

于 2012-05-08T18:57:38.903 回答