Php 如何对MySQL表中的大型多维数组进行排序
我有一个MySQL表,其中包含客户可以订购的所有可能产品的列表。此表的(非常)简化版本如下所示:Php 如何对MySQL表中的大型多维数组进行排序,php,mysql,arrays,multidimensional-array,pdo,Php,Mysql,Arrays,Multidimensional Array,Pdo,我有一个MySQL表,其中包含客户可以订购的所有可能产品的列表。此表的(非常)简化版本如下所示: ID | productid | price | age_min | age_max | type ======================================================================= 1 | baseball_1 | 12.34 | 18 | 21
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美元
- 高尔夫1-4.99美元
- 网球1-9.99美元
使现代化 虽然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的项目的productid和价格”根据数据库的大小,此解决方案可能不起作用,但通常我在较小规模上的工作方式是: 将数据库结果循环到我设计的数组中 所以我可能有
Array['baseball'][0]['price'] = 15.99
Array['baseball'][1]['price'] = 18.99
循环遍历我创建的数组以分析结果
在一个较大的数据库中,您将需要一个不同的解决方案,因为这将使您多次循环结果…您不需要多维数组 只需按类型对查询结果排序,然后在数组中循环。执行此操作时,请在第一个项目之前插入标题,然后在类型更改的每个项目之前插入标题 如果您有一个正确规范化的数据库,那么您还应该有一个
产品类型
表来保存您的产品类型ID和名称;在这种情况下,考虑<代码>连接< /代码>。然后,您的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']);
}
然后,您逐步完成结果集,如下所示:
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']);
}
$current_type='not_a_string';
while($row=get_next_row_from_database){
如果($current\u type!=$row['type\u id'])){
echo'.htmlspecialchars($row['type_name'])。';
$current_type=$row['type_id'];
}
printf(“%s-$%2.2f”,htmlspecialchars($row['name']),$row['price']);
}
这种方法使用恒定内存(在web服务器上,而不是数据库上)和线性时间
您还应该考虑对数据的分页:不要同时查询所有行,而是运行<代码>计数(*)< /代码>查询以获得行的总数,然后使用<代码>限制>代码>只获取当前页的行(您可能还希望通过子句指定<代码>顺序以使页更有意义).
我认为这不需要多维数组。我认为,当你来到一个新的小组时,你只需要在你的行中循环并更改标题 对于这个答案,我使用了一种稍微不同的方法,将每一行粘贴到一个数组中,然后对它们进行内爆,以便保留格式//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>";
您可以通过HTML表单提交(导致页面重新加载)或通过AJAX调用它。但不管怎样,我看不出执行
fetchAll
并将结果存储在数组中有什么好处。你确定多维数组真的是你想要的吗?我已经多次看到类似的问题,今天早上刚刚回答了另一个问题:。这就是你遇到的问题吗?@Travesty3-我不是来自两张桌子作为你的原始海报,仍然有些不同,尽管我相信你改变标题的方式非常有趣,也许是我想要达到的。我先来讨论一下。当我的HTML输出具有良好的格式(制表符、换行符等)时,我有点强迫症,这就是字符串中出现\n
和\t
的原因。当您运行PHP脚本时,可以更容易地找出出现问题的地方,然后查看源代码以查看实际生成的HTML。您应该对正确转义HTML输出保持谨慎。PHP当然不会让你的生活变得轻松,但如果你不适当地使用htmlspecialchars()
和朋友,你就应该成为XSS的朋友。我正在仔细考虑这一点,尽管我会继续回答这个问题,但它极大地限制了我转换数据的能力。在这一点上,一切都是关于我如何在数据库中存储东西。例如,如果我知道一个客户标题将包含多个项目(例如棒球和高尔夫将一起列出),则