php - 使用 PHP 在 MySQL DB 中的项目列表中排序标题
问题描述
希望有人知道查询/处理这些标题的好方法......
例如,如果您有一个食谱,它可能看起来像这样:(带有标题和成分)
沙拉
- 新鲜生菜
- 切碎的胡萝卜
- 新鲜草莓
敷料
- 尖酸刻薄
- 糖
- 肉桂
装饰
- 杏仁片
在 MySQL 数据库中,我将把这些数据存储在一个配方表中。所以这个食谱可能看起来像这样:
+----+---------------+-----------------+--------------------+---------------------+-----------+---------+-----------+---------+-----------+---------+
| id | ingredient_1 | ingredient_2 | ingredient_3 | ingredient_4 etc... | heading_a | h_a_pos | heading_b | h_b_pos | heading_c | h_c_pos |
+----+---------------+-----------------+--------------------+---------------------+-----------+---------+-----------+---------+-----------+---------+
| 1 | Fresh Lettuce | Chopped carrots | Fresh Strawberries | Vinegar | Salad | 1 | Dressing | 4 | Garnish | 7 |
+----+---------------+-----------------+--------------------+---------------------+-----------+---------+-----------+---------+-----------+---------+
成分都存放在一起,标题存放在一起。(不同的食谱将需要不同的标题和与成分相关的不同位置。)这里的标题位置(h_a_pos 等)表示成分 # 以在前面列出标题。
在查询它以显示它时,如果我运行一个简单的 SQL 查询:
SELECT * FROM recipes WHERE id = 1;
那只会给我一个所有东西的清单。这是一个 SQL 小提琴:http ://sqlfiddle.com/#!9/942d8a3/1/0
使用 PHP,我可以获取结果并将其放入数组中。而且我确信有某种方法可以对它们进行排序,但我正在画一个空白......
$response = []; // blank array
$sql_retrieve = $con->prepare("SELECT * FROM recipes WHERE id = 1");
$sql_retrieve->execute();
$result = $sql_retrieve->get_result();
if($result->num_rows>0){
while($row=$result->fetch_assoc()){
$response[] = $row;
} // end of while
} // end of num_rows
print_r($response); // display response pre-sorting
// sort array -- not working
usort($response, function($a, $b) {
return $a['h_a_pos'] <=> $b['h_b_pos'];
});
// would need something to order it in relation to the ingredients...
echo '<br /><br />';
print_r($response); // display response post-sorting
我可以更改数据库结构,但如果可能的话,我更愿意将其保留在一个表中。(我意识到某些成分可能未标准化,但我也没有在此示例中列出数量等。)
有人对如何存储标题有任何想法吗?我基本上只需要知道它应该是一个标题(因此可以适当地格式化),文本应该是什么,以及在哪个成分编号之前显示它。(我永远不会查询标题,所以如果这可以更好地序列化存储,那可能是一个选择......)
解决方案
你有什么不正常。例如,如果您决定想要一个复杂的配方,其中成分多于列,或者成分标题多于列,您就会遇到麻烦。要吸取的重要教训是,数据库不是电子表格。
这是更接近您想要的数据库结构的东西:
CREATE TABLE categories (id SERIAL, name VARCHAR(32));
CREATE TABLE ingredients (id SERIAL, category_id BIGINT UNSIGNED NOT NULL, name VARCHAR(32));
CREATE TABLE recipes (id SERIAL, name VARCHAR(32));
CREATE TABLE ingredients_recipes (recipe_id BIGINT UNSIGNED NOT NULL, ingredient_id BIGINT UNSIGNED NOT NULL);
显然,您还需要一些外键约束来强制表之间的链接,但我们将在这里跳过。用你的成分填充它:
INSERT INTO categories VALUES (1, 'Salad'), (2, 'Dressing'), (3, 'Garnish');
INSERT INTO ingredients VALUES (1, 1, 'Fresh Lettuce'), (2, 1, 'Chopped Carrots'), (3, 1, 'Strawberries'), (4, 2, 'Balsamic Vinegar'), (5, 2, 'Olive Oil'), (6, 3, 'Sliced Almonds');
INSERT INTO recipes VALUES (1, 'My Salad');
INSERT INTO ingredients_recipes VALUES (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6);
现在,可以使用简单的连接来提取完整的配方:
SELECT r.name AS recipe, c.name AS category, i.name AS ingredient
FROM ingredients i
LEFT JOIN categories c ON (i.category_id = c.id)
LEFT JOIN ingredients_recipes ON (ingredient_id = i.id)
LEFT JOIN recipes r ON (recipe_id = r.id)
WHERE r.id = ?
ORDER BY c.id ASC
这里有一个小提琴来说明这一点:http ://sqlfiddle.com/#!9/aecbbd/1
(请注意,“标题”的顺序必须在创建时单独定义。在这种情况下,我只是按 ID 排序。)
现在,在您的 PHP 中,您可以轻松地执行此查询并按类别对成分进行分组:
$stmt = $con->prepare($query);
$stmt->bind_param("i", $recipe_id);
$stmt->execute();
while ($row = $stmt->fetch_assoc()) {
$name = $row["recipe"];
$ingredient_types[$row["category"]][] = $row["ingredient"];
}
在显示过程中,只需循环遍历数组:
<h1>How to make <?= $name ?></h1>
<?php foreach($ingredient_types as $category=>$ingredients): ?>
<h2><?= $category ?></h2>
<ul>
<?php foreach ($ingredients as $ingredient): ?>
<li><?= $ingredient ?></li>
<?php endforeach ?>
</ul>
<?php endforeach ?>
您的问题提到了数量,这些将ingredients_recipes
作为附加列存储在数据透视表中,并且可以很容易地被拉入SELECT
子句。
推荐阅读
- python - get_dummies() 函数是否会更改列的 dtype?
- mongodb - MongoDB 更改流事件:替换与更新?
- javascript - 如何查看 javascript 函数的代码?
- android - Google 自己的 MapsActivity 如何在三星手机上导致 ClassNotFoundException?
- go - 是否有任何系统调用可以在 golang 中捕获 ctrl+v 或 shift+insert?
- google-sheets - 带有 order by 和 null 的 importrange 查询
- asp.net-mvc - 在asp.net MVC4中显示时图像变白
- javascript - 如何在javascript中覆盖嵌套数组对象
- javascript - jQuery最接近选择器不起作用并滚动并聚焦到一个类
- arrays - VBA如何直接访问字典键元素