使用SQL和PHP从不同的引用表中获取层次树

温泽尔

我有多个具有相似基本结构的表:

biopsy_p0
id | biopsy_id    | introduced

biopsy_p1
id | biopsy_p0_id | introduced

biopsy_p2
id | biopsy_p1_id | introduced

我的目标是获取依赖项之间的树状视图

biopsy_p0.id-> biopsy_p1.biopsy_p0_id-> biopsy_p2.biopsy_p1_id

我尝试仅使用SQL来执行此操作,但是从我的问题可以看出,我对此并不十分了解。到目前为止,我能找到的所有内容都是关于分层树的参考。但是那些总是只使用一个带有内部引用的表。

---更新:现在我可以在PHP上使用它了,这确实不是一个很好的解决方案,我希望我可以在SQL中使用它,这样扩展起来会更好一些:

PHP代码:

  $database = DatabaseFactory::getFactory()->getConnection();
      // Get all p0 element asociated with the biopsy
      $sql = "SELECT *
              FROM biopsy_p0
              WHERE biopsy_id = :id";
      $query = $database->prepare($sql);
      $query->execute(array(':id' => $id));
      $p0 = $query->fetchAll();

      // Get all p1 elements
      $sql="SELECT *
            FROM biopsy_p0 as p0
            RIGHT JOIN biopsy_p1 as p1
            ON p0.id=p1.biopsy_p0_id
            WHERE biopsy_id = :id;";

      $query = $database->prepare($sql);
      $query->execute(array(':id' => $id));
      $p1 = $query->fetchAll();

      for ($i=0; $i < count($p0); $i++)
      {
        $p1Array = new ArrayObject();
        foreach ($p1 as $key => $value)
        {
          if ($value->biopsy_p0_id == $p0[$i]->id)
          {
             $p1Array->append($value);
          }
          $p0[$i]->p1 = $p1Array;
        }
        unset($p1Array);
      }
      if ($p0 != NULL){
        return $p0;
      }
      return FALSE;

结果:这正是我所需要的,但是PHP太凌乱了,而且随着我想检查的每个子级别,它的复杂性都会增加。

 details:   Array
(
    [0] => stdClass Object
        (
            [id] => 1
            [biopsy_id] => 226
            [introduced] => 2014-12-31
            [p1] => ArrayObject Object
                (
                    [storage:ArrayObject:private] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [id] => 1
                                    [biopsy_id] => 226
                                    [introduced] => 2015-03-18
                                    [biopsy_p0_id] => 1
                                )

                            [1] => stdClass Object
                                (
                                    [id] => 3
                                    [biopsy_id] => 226
                                    [introduced] => 2015-03-17
                                    [biopsy_p0_id] => 1
                                )

                            [2] => stdClass Object
                                (
                                    [id] => 4
                                    [biopsy_id] => 226
                                    [introduced] => 2015-03-18
                                    [biopsy_p0_id] => 1
                                )

                        )

                )

        )

    [1] => stdClass Object
        (
            [id] => 2
            [biopsy_id] => 226
            [introduced] => 2014-12-31
            [p1] => ArrayObject Object
                (
                    [storage:ArrayObject:private] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [id] => 2
                                    [biopsy_id] => 226
                                    [introduced] => 2015-03-31
                                    [biopsy_p0_id] => 2
                                )

                            [1] => stdClass Object
                                (
                                    [id] => 6
                                    [biopsy_id] => 226
                                    [introduced] => 2015-03-01
                                    [biopsy_p0_id] => 2
                                )

                        )

                )

        )

    [2] => stdClass Object
        (
            [id] => 3
            [biopsy_id] => 226
            [introduced] => 2014-12-31
            [p1] => ArrayObject Object
                (
                    [storage:ArrayObject:private] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [id] => 5
                                    [biopsy_id] => 226
                                    [introduced] => 2015-03-11
                                    [biopsy_p0_id] => 3
                                )

                        )

                )

        )

)

SQL数据:

CREATE TABLE IF NOT EXISTS `biopsy` (
  `id` int(11) unsigned NOT NULL,
  `creation_date` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=228 DEFAULT CHARSET=latin1;

INSERT INTO `biopsy` (`id`, `creation_date`) VALUES
(226, '2015-03-08'),
(227, '2015-03-08');

CREATE TABLE IF NOT EXISTS `biopsy_p0` (
`id` int(11) unsigned NOT NULL,
  `biopsy_id` int(11) unsigned NOT NULL,
  `introduced` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;

INSERT INTO `biopsy_p0` (`id`, `biopsy_id`, `introduced`) VALUES
(1, 226, '2014-12-31'),
(2, 226, '2014-12-31'),
(3, 226, '2014-12-31'),
(4, 227, '2015-03-14'),
(5, 255, '2015-03-10'),
(6, 255, '2015-03-12');

CREATE TABLE IF NOT EXISTS `biopsy_p1` (
`id` int(11) unsigned NOT NULL,
  `biopsy_p0_id` int(11) unsigned NOT NULL,
  `introduced` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;

INSERT INTO `biopsy_p1` (`id`, `biopsy_p0_id`, `introduced`) VALUES
(1, 1, '2015-03-18'),
(2, 2, '2015-03-31'),
(3, 1, '2015-03-17'),
(4, 1, '2015-03-18'),
(5, 3, '2015-03-11'),
(6, 2, '2015-03-01');

也许最好有一个层次结构表通过ID引用另一个存储实际数据的表...这样我就只涉及两个表,如果添加新元素,它会更加灵活...

伦纳特

让我们从声明密钥开始:

CREATE TABLE IF NOT EXISTS `biopsy` (
  `id` int(11) unsigned NOT NULL primary key,
  `creation_date` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=228 DEFAULT CHARSET=latin1;

INSERT INTO `biopsy` (`id`, `creation_date`) VALUES
(226, '2015-03-08'),
(227, '2015-03-08');

CREATE TABLE IF NOT EXISTS `biopsy_p0` (
`id` int(11) unsigned NOT NULL primary key,
`biopsy_id` int(11) unsigned NOT NULL,
`introduced` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;

alter table biopsy_p0 add constraint fk_biopsy
    foreign key (biopsy_id)
    references biopsy (id)
        on update cascade
        on delete cascade;

INSERT INTO `biopsy_p0` (`id`, `biopsy_id`, `introduced`) VALUES
(1, 226, '2014-12-31'),
(2, 226, '2014-12-31'),
(3, 226, '2014-12-31'),
(4, 227, '2015-03-14');

-- violates the f.k. introduced
-- (5, 255, '2015-03-10'),
-- (6, 255, '2015-03-12');

CREATE TABLE IF NOT EXISTS `biopsy_p1` (
  `id` int(11) unsigned NOT NULL primary key,
  `biopsy_p0_id` int(11) unsigned NOT NULL,
  `introduced` date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;

alter table biopsy_p1 add constraint fk_biopsy_p0
    foreign key (biopsy_p0_id)
    references biopsy_p0 (id)
        on update cascade
        on delete cascade;

INSERT INTO `biopsy_p1` (`id`, `biopsy_p0_id`, `introduced`)     
VALUES
(1, 1, '2015-03-18'),
(2, 2, '2015-03-31'),
(3, 1, '2015-03-17'),
(4, 1, '2015-03-18'),
(5, 3, '2015-03-11'),
(6, 2, '2015-03-01');

我建议您为它们的名称命名,即不要命名id列id并在模型中的其他地方更改名称。例子:

CREATE TABLE IF NOT EXISTS biopsy (
  biopsy_id int unsigned NOT NULL primary key,
  creation_date date NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=228 DEFAULT CHARSET=latin1;

但我会把它放在一边。现在我们知道数据是一致的:

select x.id as biopsy_id, x.creation_date
     , y.id as biopsy_p0_id, y.introduced as biopsy_p0_introduction
     , z.id as biopsy_p1_id, z.introduced as biopsy_p1_introduction 
from biopsy as x 
left join biopsy_p0 as y 
    on y.biopsy_id = x.id 
left join biopsy_p1 as z 
    on z.biopsy_p0_id = y.id 
order by x.id, y.id, z.id;

+-----------+---------------+--------------+------------------------+--------------+------------------------+
| biopsy_id | creation_date | biopsy_p0_id | biopsy_p0_introduction | biopsy_p1_id | biopsy_p1_introduction |
+-----------+---------------+--------------+------------------------+--------------+------------------------+
|       226 | 2015-03-08    |            1 | 2014-12-31             |            1 | 2015-03-18             |
|       226 | 2015-03-08    |            1 | 2014-12-31             |            3 | 2015-03-17             |
|       226 | 2015-03-08    |            1 | 2014-12-31             |            4 | 2015-03-18             |
|       226 | 2015-03-08    |            2 | 2014-12-31             |            2 | 2015-03-31             |
|       226 | 2015-03-08    |            2 | 2014-12-31             |            6 | 2015-03-01             |
|       226 | 2015-03-08    |            3 | 2014-12-31             |            5 | 2015-03-11             |
|       227 | 2015-03-08    |            4 | 2015-03-14             |         NULL | NULL                   |
+-----------+---------------+--------------+------------------------+--------------+------------------------+
7 rows in set (0.00 sec)

剩下的只是纯粹的演示,最好在php中完成。

关于您的一般性问题,最好将结构信息保留在一个表中,我想说的是,如果您的固定级别较少,那么解决方案就可以了。

对于大量级别或数量未知的情况,您需要某种递归结构(请注意,您还需要询问此类问题的方法,如今大多数DBMS:s都具有递归公用表表达式,而MySQL却没有。您可以使用变量来解决某些问题,但是很快就会变得混乱。Troels Arvin在以下位置有一组链接:

http://troels.arvin.dk/db/rdbms/links/#hierarchical

您可能会发现有用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

SQL如何从不同的表中获取值?

来自分类Dev

SQL:如何使用连接从不同的表中获取多行?(初学者的问题)

来自分类Dev

如何从不同的表中选择相关数据,并使用它显示mysql和php中的趋势?

来自分类Dev

使用Javascript从不同表中的表行中获取元素

来自分类Dev

我想使用 postgresql 函数从不同的不同表名中获取数据

来自分类Dev

如何从不同的表中获取记录并忽略SQL中的重复日期?

来自分类Dev

使用连接表从不同的表中获取两个总和

来自分类Dev

如何从不同的表中获取数据到单表

来自分类Dev

单个SQL从不同的表中检索不同的信息

来自分类Dev

我如何从不同的表进行计数和求和(SQL)

来自分类Dev

从不同表的2列中获取总和

来自分类Dev

改进此查询以从不同的表中获取数据

来自分类Dev

按时间顺序从不同的表中获取帖子

来自分类Dev

PDO从不同的表中获取当前添加的ID?

来自分类Dev

从不同表中的两列获取重复项

来自分类Dev

使用python中的yahoo和pandas_datareader从不同市场获取市场数据

来自分类Dev

使用SQL存储过程从不同的表中删除多个记录

来自分类Dev

如何使用SQL简单查询从不同表中插入数据

来自分类Dev

使用 SQL Server 从每个表和每一列中获取不同的值

来自分类Dev

获取不同表SQL中的重复项和更新列

来自分类Dev

将Weka树转换为SQL层次表的层次结构

来自分类Dev

将Weka树转换为SQL层次表的层次结构

来自分类Dev

使用案例从SQL Server中的不同表中获取值

来自分类Dev

从不同的表获取结果-加入

来自分类Dev

CakePHP如何从不同的表获取照片?

来自分类Dev

从不同的表中获取最小值并保存在结果表中

来自分类Dev

如果结果不同,如何运行查询以从不同的表中获取数据

来自分类Dev

在SQL Server中获取引用表

来自分类Dev

从引用表中获取值的 SQL 查询

Related 相关文章

  1. 1

    SQL如何从不同的表中获取值?

  2. 2

    SQL:如何使用连接从不同的表中获取多行?(初学者的问题)

  3. 3

    如何从不同的表中选择相关数据,并使用它显示mysql和php中的趋势?

  4. 4

    使用Javascript从不同表中的表行中获取元素

  5. 5

    我想使用 postgresql 函数从不同的不同表名中获取数据

  6. 6

    如何从不同的表中获取记录并忽略SQL中的重复日期?

  7. 7

    使用连接表从不同的表中获取两个总和

  8. 8

    如何从不同的表中获取数据到单表

  9. 9

    单个SQL从不同的表中检索不同的信息

  10. 10

    我如何从不同的表进行计数和求和(SQL)

  11. 11

    从不同表的2列中获取总和

  12. 12

    改进此查询以从不同的表中获取数据

  13. 13

    按时间顺序从不同的表中获取帖子

  14. 14

    PDO从不同的表中获取当前添加的ID?

  15. 15

    从不同表中的两列获取重复项

  16. 16

    使用python中的yahoo和pandas_datareader从不同市场获取市场数据

  17. 17

    使用SQL存储过程从不同的表中删除多个记录

  18. 18

    如何使用SQL简单查询从不同表中插入数据

  19. 19

    使用 SQL Server 从每个表和每一列中获取不同的值

  20. 20

    获取不同表SQL中的重复项和更新列

  21. 21

    将Weka树转换为SQL层次表的层次结构

  22. 22

    将Weka树转换为SQL层次表的层次结构

  23. 23

    使用案例从SQL Server中的不同表中获取值

  24. 24

    从不同的表获取结果-加入

  25. 25

    CakePHP如何从不同的表获取照片?

  26. 26

    从不同的表中获取最小值并保存在结果表中

  27. 27

    如果结果不同,如何运行查询以从不同的表中获取数据

  28. 28

    在SQL Server中获取引用表

  29. 29

    从引用表中获取值的 SQL 查询

热门标签

归档