[英]MYSQL query problem - can't figure it out
嗨,我有个大问题……听起来很简单,但实际上非常复杂
我有两个mysql表:
info_cat (id, name)
info_subcat (id, id_info_cat, name)
我想向用户显示info_cat.name
然后再显示info_subcat.name
但问题是info_cat.name
我只想出现一次。 像这样:
笔记本电脑
硬碟
所以通常我会这样查询(老式)
$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
我只想回显一次笔记本电脑,一次回显HDD,然后再回显其子类别名称。 我怎样才能做到这一点 ?
Pleaseee ....
谢谢
当嵌套循环完美地描述问题(列表中的列表)时,嵌套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通常会执行您期望的操作)。
在查询中使用分组依据
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名称=最后一个info_cat名称,如果两者相等,则不要添加它,否则添加它,例如(这是下面的psedocode)
$lastInfoCatName = $row['name'];
while ($row != null)
{
if ($lastInfoCatName != $row['name']
{
$lastInfoCatName = $row['name']
//work on creating the table
}
尝试使用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
有两种方法可以做到这一点。 为了完整起见,我将两者都列出。
方法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”
您发布的结果看起来像mysql结果,而不是根据您的脚本输出的php。
遍历主要类别,它将回显名称,并遍历其子类别,并回显子名称并继续。
在您的示例中,没有地方会产生这样的输出...
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! :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.