【问题标题】:Selecting rows on specific level with SQL使用 SQL 选择特定级别的行
【发布时间】:2015-12-27 19:30:06
【问题描述】:

我有一个这样的 MySQL 表:

id     | upperId   | title
-------+-----------+---------
1      | 0         | World
2      | 1         | Europe
3      | 1         | Asia
4      | 2         | Germany
5      | 4         | Berlin
...

你明白了:

  • 世界
    • 欧洲
      • 德国
        • 柏林
    • 亚洲
      • 中国
        • 北京
      • 日本

现在,我需要一个 SQL 查询来从region 中选择特定级别的所有区域,比如第三个。在这个例子中,这将是德国、日本和中国。对于第二个级别,它将是欧洲和亚洲。

如果查询对所有不同级别都灵活,而不是特定于一个级别,那就更好了。

有没有 SQL 方法可以做到这一点,还是我需要用 PHP 循环所有区域?

【问题讨论】:

  • 你能显示你的查询吗?
  • 请导出查询结果...
  • @NullVoid 对不起,你是什么意思?我不知道该怎么做,所以我想看看如何为其构建查询。
  • 一个简单的“从 tb1 WHERE upperId=2 选择标题”不起作用吗?
  • 啊,我明白了。我需要该级别的所有行。我更新了这个例子。因此,不仅是欧洲下方的行,还有亚洲下方的行。

标签: php mysql sql database


【解决方案1】:

对于特定级别(在本例中为第三级),您可以这样做:

select l3.*
from region l1, region l2, region l3
where l1.upperId = 0
and l2.upperId = l1.id
and l3.upperId = l2.id

【讨论】:

  • 谢谢!您将获得通用的奖励积分(即不特定于第三级)! :)
【解决方案2】:

我认为您应该做的最好的事情是添加一个“深度”列。查询会更简单,执行起来更快。

【讨论】:

    【解决方案3】:

    我假设您正在寻找通用解决方案。这里的重点是,您正在做的是隐式地对树进行递归搜索,据我所知,MySQL 没有递归操作。

    因此,您必须自己在代码中使用递归(或等效迭代)。

    根据您的项目中实现的内容,另一种解决方案可能是使用Nested Set 而不是“普通”树。使用嵌套集数据结构,您的查询将引导您寻找足够的 .lft 和 .grt 值。简单方便。

    不幸的是,将表迁移到 NestedSet 结构并不简单。如果您的表已填充并在生产中,我想用 PHP 编写循环可能会快得多...

    【讨论】:

      【解决方案4】:

      也许是这样的? (未经过全面测试,但我认为它会起作用)

      <?php
      
      mysql_connect('localhost','root','yourpw');
      mysql_select_db('db') or die (mysql_error());
      
      $strSQL = "Select title FROM table";  
      $objQuery = mysql_query($strSQL) or die ("Error Query [".$strSQL."]"); 
      
      $i = 0;
      while($objResult = mysql_fetch_array($objQuery))
      {
      $i++;
      
      $strSQL1 = "Select title FROM table Where upperId='".$i."'";  
      $objQuery1 = mysql_query($strSQL1) or die ("Error Query [".$strSQL1."]"); 
      $objResult1 = mysql_fetch_array($objQuery1);
      
      echo "<br>";
      echo $objResult1["title"];
      }
      
      ?>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多