一个加入的MySQL结果在PHP
做一个项目的allnighter的有序输出,我的脑子一片空白ATM ...简单的问题,真正做到:一个加入的MySQL结果在PHP
我有两个MySQL表,产品和类别。每个产品都属于一个类别。每个类别都有几个产品。
SELECT
p.uid as product_uid, p.name_NL as product_name, p.price as product_price,
c.uid as category_uid, c.name_NL as category_name
FROM
product p, category c
WHERE
p.category_uid = c.uid
这给了我一个很好的概述,在其各自的类别中的所有产品。我的问题是关于在页面上输出这个数据。我的目标是:
<h1>Category name</h1>
<p>Product in this category</p>
<p>Other product in this category</p>
<h1>Next category</h1>
<p>Product in next category</p>
我的想法现在完全是空白。如何去做这件事?
我想避免做子查询(如果可能的话)。
亲切的问候,
中号
如何添加ORDER BY category_uid
以便产品在您的SQL查询中按类别排序。然后使用PHP,遍历每个产品(行),当遇到新类别时,添加一个新标题。
例子:
<?php
// ...
$previous_category_uid = null;
// Loop through each row.
while ($row = $result->fetch_assoc())
{
// If the category UID is not the same as the one from the previous row, add a header.
if ($previous_category_uid != $row['category_uid'])
{
echo '<h1>' . $row['category_name'] . '</h1>';
$previous_category_uid = $row['category_uid'];
}
}
这种方法的好处是,你不必嵌套查询。一个查询就足够了。
谢谢,这似乎是我当前设置最容易实现的解决方案! – maartenmachiels
不客气! –
假设你正在寻找在每个类别中字母排序的类别名称及产品:
SELECT
p.uid as product_uid, p.name_NL as product_name, p.price as product_price,
c.uid as category_uid, c.name_NL as category_name
FROM product p INNER JOIN category c ON p.category_uid = c.uid
ORDER BY category_name, product_name
这也查询的笛卡尔积和WHERE
转换为内连接。
要输出您想要的标题,只需循环返回的行,并跟踪您所在的类别。只要当前行的类别与上一个类别不同,就会打印一个新的h1
新类别并更新存储的“当前”类别。
谢谢。在这种情况下使用Inner Join有很大的优势吗?我的方式连接表是不好的做法? – maartenmachiels
在仅由逗号分隔的'FROM'子句中指定多个表将执行笛卡尔积,这会导致两个表中的行的每种可能组合。然后,使用WHERE条款消除所有“额外”结果。内部连接正是为这个用例设计的,并且避免了所有那些中间“额外”行的生成。查询优化器有时可以检测您的意图并避免笛卡尔产品,但内部联接实际上就是您想要的。 –
谢谢,约翰,我一定会避免这些笛卡尔联接。 – maartenmachiels
一般来说,你有两个选择:
- 获取所有数据一次(像你现在这样做),然后按类别使用PHP或者预先排序的数据。然后做你的输出循环这个数组。所以1个查询,2 + n个循环(其中n是类别的数量)。
- 获取所有类别,然后循环输出。在每次迭代中,您需要查询该循环的所有产品。所以1 + n个查询,1 + n个循环(其中,再次,n是类别的数量)。
选项2可能更直接,但显然有更多的查询。最后,这是你的呼叫。
如何选择所有类别,然后遍历它们。在循环中,选择类别中的所有产品,然后循环输出。 –
那么两个查询,然后将它们各自的结果存储在两个数组中,然后像那样工作? – maartenmachiels
两个查询,一个嵌套在第一个结果的循环中。 –