如何使用mySQL和PHP实现所描述的排序?

4

我有一张名为"categories"的表格,包含以下三个字段

cat     | order | id
--------|-------|----
News    |  3    | 23
Hi-Tech |  2    | 15
Biz     |  5    | 8
Health  |  1    | 3

另外,我还有一张名为"links"的表格如下:
link    | order | cat-id
--------|-------|-------
link1   |  2    | 23
link2   |  8    | 15
link3   |  5    | 8
link4   |  6    | 15
link5   |  2    | 15
link6   |  4    | 23
link7   |  1    | 3
link8   |  1    | 8

我想要实现的目标是对 分类 进行排序,并在每个分类下按照 分类id / id 排序其下的 链接,如下所示:

健康
link7

高科技
link5
link4
link2

新闻
link1
link6

商业
link8
link3

我已经成功地显示了排序后的 分类,但在此之后我失去了它。 我的目标是在页面上显示这个,所以我想我需要使用 PHP 和 MySQL。

1
仅SQL查询还是PHP和SQL? - Seder
@UserB,我已经更新了我的问题。我的目标是在页面上展示它,所以我想我必须使用PHP和MySQL。 - EnexoOnoma
尝试使用PHP和MySQL测试我的答案。 - Seder
2
嘿,伙计,采用Paolo的答案,那是你问题的最佳解答。 - Vipin Jain
10个回答

16

这个查询很简单:

SELECT c.cat, l.link, c.id
FROM links l INNER JOIN categories c
ON l.cat-id = c.id
ORDER BY c.`order`, l.`order`

这是实际演示链接

为了在页面上展示它,代码看起来应该像这样:

mysql_connect(<host>, <username>, <password>);

$q = mysql_query("<query from above>");
$last_cat = 0;
while($row = mysql_fetch_assoc($q)) {
    if($row['id'] != $last_cat) {
        print '<h3>' . $row['cat'] . '</h3>';
        $last_cat = $row['id'];
    }
    print $row['link'] . '<br>';
}

我想我必须使用PHP和mySQL,因为我将在页面上显示它。 - EnexoOnoma
1
当我写我的文章时,我没有看到你的帖子,但我们使用了相同的别名和变量名。有趣。 - Taha Paksu
3
在数据库和编程术语中,这些数字是小菜一碟。在进入分页等操作之前,这段代码几乎是处理这个问题的标准方式。它只需要向数据库发送一次请求并在一个循环中打印出所有内容。从易用性角度来看,展示给用户60x5似乎有点过多,但这超出了本问题的范围... - Paolo Bergantino
仅补充一下@PaoloBergantino上面提到的内容。构建表结构的方式比行数更重要。如果链接都放在正确位置并且索引已经正确定义,对于mysql来获取数据不应该是问题。要评估您的查询语句,您可以简单地使用“explain”。 - Jermin Bazazian
我唯一可能补充的是,如果你想要一个可移植的格式,你可以从数据中构建一个数组 $array[$row['cat']][] = $row['link'],如果需要的话,这样可以进行一些精细的操作。 - Malovich
显示剩余4条评论

5

我心里有个想法,没有测试过,但大致是这样的:

$q = mysql_query("select * from categories c 
      left join links l 
      on l.cat-id=c.id 
      order by c.order,l.order");

$last_cat = -1;

while($row=mysql_fetch_assoc($q)){
    if($last_cat!=$row["cat"]){
        echo "<br><b>".$row["cat"]."</b><br>";
        $last_cat=$row["cat"];
    }
    echo $row["link"]."<br>";
}

请假设“类别”表将有大约60行,每个类别至少有5个链接。这段代码对此进行了优化吗? - EnexoOnoma
是的,SQL将返回最有效的结果,PHP将在一个循环中执行它。即使有数百个链接也没有关系。我正在使用这种方法来列出电视节目的剧集。想一想。 - Taha Paksu
当类别发生更改时,您忘记更改 last_cat =) - Paolo Bergantino

2
这将按照你在示例中描述的内容进行精确打印:
<?php
$categories = mysql_query("SELECT * FROM categories order by 'order'");
$links = mysql_query("SELECT * FROM links order by 'order'"); 
?>

<?php foreach ($categories as $key => $category): ?>
 <b><?php echo $category['cat'];?>"</b>
    <?php foreach ($links as $key => $link): ?>
      <?php if($category['id'] === $link['cat-id']): ?>
         <?php echo $link['link'];?>
      <?php endif;?>
    <?php endforeach;?>
   <br />
<?php endforeach;?>

2
<?php
// This query gets all the needed data with one shot. No need to do multiple
// queries. You can run this query in phpMyAdmin to see the result.
$query = mysql_query("
    SELECT links.link as link, categories.cat as cat FROM links
    LEFT JOIN categories ON categories.id = links.cat_id
    ORDER BY categories.order, links.order ASC");

// With this we are getting all links with correct order to an array.
$categories = array();
while ($row = mysql_fetch_array($query)) {
    $categories[$row['cat']][] = $row['link'];
}

// To see how we stored the links in the array uncomment the below line
// var_dump($categories);

// To print out the data:
foreach ($categories as $category => $links) {
    echo "<strong>".$category."</strong><br />\n";

    // implode is a built-in function that makes a string from an array.
    // You can put something between the array elements with the first parameter.
    // If you want to make some changes or print the links, use a foreach loop.
    echo implode("<br />\n", $links)."<br /><br />\n";
}
?>

这应该会精确地编写您想要的链接。


1
ORDER BY categories.order ASC, links.order ASC

1
select cat, link
from categories, links
where link.cat-id = categories.id
order by cat asc, link asc;

1
根据您的查询,如果我们需要考虑优化,我们将考虑一些情况。 情况1: 正如您所提到的,您可能会有60个链接*5个类别,这些非常容易从mysql方面处理。我们可以很好地使用SQL技术本身,并从中获得好处。
总是可以有PHP处理+ SQL的混合。 PHP的处理速度比mysql快。所以,抓住它。
您的查询也可以仅通过SQL解决,并且可以简单地使用Paolo提到的查询。 情况2: 有些情况下,参与表格之一或两者都具有太多的记录。 当两个表之间存在联接时,结果会产生大量组合即联接大小。 例如:链接(100,000)*类别(10)= 1百万 在这些情况下,您可以尝试避免连接。
您可以利用索引。 索引用于快速查找特定列值的行。 没有索引,MySQL必须从第一行开始,然后读取整个表以找到相关行。

有一些技术,比如无模式数据库(如MongoDB)使用的平面文件,不使用连接的概念。但如果你计划在一个庞大的网站上运行它(庞大意味着你需要很多服务器来托管它),那么你需要考虑一些东西。

MySQL可以很好地扩展,当你处于一个非常庞大的环境中时,你必须想出一些解决方案。

在这里,我已经解决了您的查询,而没有使用连接和任何依赖查询。我只是获取结果并仅使用数组映射技术,这样更快。

 $query = mysql_query("SELECT * FROM category order by `order` asc");
 while($row = mysql_fetch_assoc($query) ) {
     $categories[$row['id']]['cat']  = $row['cat'];
     $categories[$row['id']]['order'] = $row['order'];

 } 

 $query = mysql_query("SELECT * FROM links ORDER BY `order` ASC ");
 $count =0; 
 while($row = mysql_fetch_assoc($query) ) {
     $links[$row['cat-id']][$count]['link']  = $row['link'];
     $links[$row['cat-id']][$count]['order']  = $row['order'];
     $links[$row['cat-id']][$count]['cat-id']  = $row['cat-id'];
     $count++; 
 } 

foreach ($categories as $id=$value) {
     foreach ($links[$id] as $link_info) {

         if ($last_cat != $link_info['cat-id'])
             print '<h3' . $categories[$link_info['cat-id']]['cat'] . '</h3';

         print $link_info['link'] . '<br';
         $last_cat = $link_info['cat-id'];
     } }

0

首先,像很多人说的那样,查询是:

SELECT c.cat,c.order as catorder,c.id,l.* FROM categories as c 
INNER JOIN links as l ON (c.id = l.id-cat )
ORDER BY c.order, l.order 

所以你有一个按照这样排序的结果:

cat     | catorder | id  |  link   | order | cat-id
--------|----------|-----|---------|-------|-------
Health  |  1       | 3   |  link7  |  1    |  3
Hi-Tech |  2       | 15  |  link5  |  2    |  15
Hi-Tech |  2       | 15  |  link4  |  6    |  15
Hi-Tech |  2       | 15  |  link2  |  8    |  15
News    |  3       | 23  |  link1  |  2    |  23
News    |  3       | 23  |  link6  |  4    |  23
Biz     |  5       | 8   |  link8  |  1    |  8
Biz     |  5       | 8   |  link3  |  1    |  8  

所以...你需要制作一个“切割控制器”

$max = sizeof($arrayOfResults)
$i = 0;
while ($i < $max) {
    $current = $arrayOfResults[$i]["id"];
    print_r($arrayOfResults[$current]["cat"]);
    while ($i < $max && $arrayOfResults[$i]["id"] == $current) {
        print_r($arrayOfResults[$current]["link"]);
        $i++;
    }
}

如果您复制并粘贴这段代码,您将获得您正在查找的输出。
如果您需要解释,请问我。

-1

代码可能是这样的。

<?php
$result_catg = mysql_query("select * from categories order by order asc");
?>
<ul>
<?php
while($row_catg = mysql_fetch_array($result_catg))
{
$catg_id = $row_catg['id'];
$result_link = mysql_query("select * from links where cat_id = '$catg_id' order by order asc");
while($row_link = mysql_fetch_array($result_link))
{
?>
<li class="down"><?php echo $row_link['link']; ?></li>
<?php
}
}
?>
</ul>

在你的CSS属性中使用 "float:none" 即可解决

  • 的问题

    希望能帮到你。


    -1

    这将会给您所需的结果。

    $ds = mysql_query("select cat, id from categories order by  'order' asc");
    while($rs = mysql_fetch_row($ds))
    {
        echo"<b>".$rs[0]."<b><br/>";
        $dsLinks = mysql_query("select link from links where cat_id = '".$rs[1]."' order by 'order' asc");
        while($rsLink = mysql_fetch_row($ds))
        {
            echo"<b>".$rsLink [0]."<b><br/>";
        }
        echo"<br/>";
    }
    

    1
    在循环中进行查询不是一个好的解决方案:如果您的类别表中有100行,则需要进行101个查询!在这种情况下,您必须使用内部连接,请查看Paolo Bergantino的查询;-) - Julien

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接