Hy,我有一个很大的问题......听起来很简单但实际上很复杂
我有两个mysql表:
info_cat (id, name)
info_subcat (id, id_info_cat, name)
我想向用户显示info_cat.name
后跟info_subcat.name
,但问题是info_cat.name
我想只出现一次。
像这样:
笔记本
HDD
所以,我会像这样查询(老式的)
$query = mysql_query("SELECT * FROM info_cat");
while ($row = mysql_fetch_assoc($query)) {
$id_info_cat = $row['id'];
echo $row['name'];
$query2 = mysql_query("SELECT * FROM info_subcat WHERE id_info_cat = '$id_info_cat'");
while($row2 = mysql_fetch_assoc($query2)) {
echo $row2['nume'];
}
}
我有while within while
。
我的问题是我怎么能只用一个查询来实现这个(我想用JOIN)?
我尝试了以下命令:
SELECT info_cat.name, info_subcat.name AS name2, info_subcat.id FROM info_cat, info_subcat WHERE info_cat.id = info_subcat.id_info_cat;
但无法弄清楚如何操作数据,因为它会输出:
name name2 id
Laptop Acer 1
Laptop HP 2
Laptop Sony 3
HDD Western Digital 4
HDD Seagate 5
HDD ETC 6
我只想回复笔记本电脑一次,硬盘驱动器一次,然后是它的子名称。 我怎么能这样做?
Pleaseee ....
谢谢
答案 0 :(得分:2)
嵌套while循环没有任何问题,当他们完美地描述问题时(列表中的列表)。但是,如果您想不惜一切代价避免嵌套while循环,可以执行以下操作:
$query = mysql_query("
SELECT ic.name ic_name, isc.name isc_name
FROM info_cat ic
LEFT JOIN info_subcat isc
ON ic.id = isc.id_info_cat
ORDER BY ic_name ASC");
$last_cat = '';
while ($row = mysql_fetch_assoc($query)) {
if($row['ic_name'] != $last_cat) {
echo $row['ic_name'];
$last_cat = $row['ic_name'];
}
echo $row['name'];
}
应该可以在没有ORDER BY
语句的情况下编写上述查询,从而获得一点性能。使用ORDER BY
更明确一点,并保证(SQL标准不规定行的某些排序,可以是任何东西)结果集的正确排序和输出(尽管mysql通常做你期望的)。
答案 1 :(得分:1)
在查询中使用group by
SELECT info_cat.name, info_subcat.name AS name2, info_subcat.id FROM info_cat inner join info_subcat on info_cat.id = info_subcat.id_info_cat
group by info_cat.name
order by info_cat.name desc
然后在你的while循环中,执行if检查以查看info_cat name = last info_cat name是否相等然后不添加它,否则添加它 例如(这是下面的psedocode)
$lastInfoCatName = $row['name'];
while ($row != null)
{
if ($lastInfoCatName != $row['name']
{
$lastInfoCatName = $row['name']
//work on creating the table
}
答案 2 :(得分:1)
尝试使用GROUP BY和GROUP_CONCAT。
SELECT
info_cat.name,
GROUP_CONCAT(info_subcat.name ORDER BY info_subcat.name SEPARATOR ', ')
FROM
info_cat
LEFT JOIN
info_subcat ON (info_car.id = info_subcat.id_info_cat)
GROUP BY
info_cat.id
答案 3 :(得分:1)
有几种方法可以做到这一点。为了完成,我将列出两者。
方法#1
$query = <<<SQL
SELECT
ic.name catname
, is.name subcatname
FROM
info_cat ic
JOIN info_subcat is ON (ic.id = is.info_cat_id)
SQL;
$result = mysql_query($query);
$cats = array();
while ($row = mysql_fetch_object($result)) {
if ( ! isset($cats[$result->catname]) ) {
$cats[$result->catname] = array();
}
$cats[$result->catname][] = $result->subcatname;
}
foreach ($cats as $catname => $subcats) {
echo "$catname<br /> <ul>";
foreach ($subcats as $subcat) {
echo "<li>$subcat</li>";
}
echo "</ul>";
}
方法#2
$query = <<<SQL
SELECT
ic.name catname,
GROUP_CONCAT(is.name) subcatnames
FROM
info_cat ic
JOIN info_subcat is ON (ic.id = is.info_cat_id)
SQL;
$result = mysql_query($query);
while ($row = mysql_fetch_object($result)) {
echo "$row->name<br /><ul>"
foreach (explode(',', $row->subcatnames) as $subcatname) {
echo "<li>$subcatname</li>";
}
echo "</ul>";
}
由于其他人也会建议它,你应该使用PDO和PHPTAL,当你创建一个表时,你应该给“id”列一个引用表的名称,如“icID”和“isID”
答案 4 :(得分:0)
您发布的结果看起来像是mysql结果,而不是根据您的脚本输出的PHP。
迭代主要类别,它将回显名称,它将遍历其子类别并回显子名称并继续前进。
在你的例子中没有任何地方可以产生这样的输出......
答案 5 :(得分:0)
SELECT info_cat.name, GROUP_CONCAT(info_subcat.name) AS name2
FROM info_cat, info_subcat
WHERE info_cat.id = info_subcat.id_info_cat
GROUP BY info_cat.name;
CONCAT! :)