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를 통해 실제 데이터를 저장하는 다른 테이블을 참조하는 하나의 계층 적 관계 테이블을 갖는 것이 더 좋을 것입니다. 그러면 두 개의 테이블 만 포함되고 새 요소가 추가되면 더 유연해질 수 있습니다.

Lennart

키를 선언하는 것으로 시작하겠습니다.

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에는 재귀 공통 테이블 표현식이 있지만 MySQL에는 없습니다. 변수로 특정 문제를 해결할 수 있지만 곧 지저분해진다.) Troels Arvin에는 다음 링크 모음이 있습니다.

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

유용하다고 생각할 수 있습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

SQL-이 쿼리를 조인하기 위해 다른 테이블에서 열 가져 오기

분류에서Dev

조인 쿼리를 사용하여 4 개의 다른 테이블에서 레코드 가져 오기

분류에서Dev

다른 테이블의 열 개수 (*)를 참조하여 한 테이블에서 데이터 가져 오기

분류에서Dev

조인 및 하위 쿼리를 사용하여 두 테이블에서 행 가져 오기

분류에서Dev

다른 테이블 SQL에서 중복 가져 오기 및 열 업데이트

분류에서Dev

다른 서버의 SQL 조인 테이블 및 가져 오기 테이블 SSMS

분류에서Dev

개발 및 프로덕션 사이트에서 Javascript를 사용하여 다른 기본 URL 가져 오기

분류에서Dev

MySQL-조인을 작성하여 다중 계층 연결된 테이블에서 데이터 가져 오기

분류에서Dev

사진 참조 및 키를 사용하여 개조 라이브러리를 사용하여 Body 응답에서 사진 가져 오기

분류에서Dev

SQL Server 쿼리를 사용하여 출석 로그 테이블 및 직원 테이블에서 null 값을 가져 오나요?

분류에서Dev

여러 테이블에서 여러 행 가져 오기 및 하나의 MySQL 쿼리를 사용하여 정렬

분류에서Dev

ID를 사용하여 다른 테이블에서 데이터 가져 오기

분류에서Dev

TREATAS를 사용하여 다른 테이블에서 측정 값 가져 오기

분류에서Dev

JPA를 사용하여 다른 테이블에서 레코드 가져 오기

분류에서Dev

쿼리에서 블로그 ID를 사용하여 블로그 카테고리 및 키워드 가져 오기

분류에서Dev

계층 구조의 하위 항목이 주어지면 INFORMIX 계층 구조 SQL로 전체 트리를 가져옵니다.

분류에서Dev

테이블의 다중 계층 구조에 대한 루트 노드 및 모든 하위 노드를 가져 오는 방법

분류에서Dev

SQL 쿼리를 사용하여 데이터 가져 오기 및 Asp의 if 조건

분류에서Dev

트리거 삭제 및 다른 테이블에서 필드 가져 오기

분류에서Dev

SQL Server에 대한 다른 쿼리에서 사용하기 위해 한 테이블에서 데이터를 가져 오나요?

분류에서Dev

SQL : 다른 테이블에서 사용자 정보 및 최신 날짜 기록 가져 오기

분류에서Dev

다른 SQL 테이블에서 데이터 가져 오기 및 comboBox에 추가

분류에서Dev

함수를 사용하여 뷰 뷰에서 참조하는 테이블 가져 오기

분류에서Dev

행 및 열 번호를 사용하여 다른 시트에서 데이터 가져 오기

분류에서Dev

mySql (phpMyAdmin)을 사용하여 다른 테이블에서 데이터를 가져 오는 테이블 만들기

분류에서Dev

importrange를 사용하여 다른 시트에서 텍스트 및 특정 텍스트 수 가져 오기

분류에서Dev

하위 쿼리를 사용하는 동안 다른 테이블에서 이름 가져 오기

분류에서Dev

쿼리를 사용하여 HP Vertica에서 테이블 생성 -SQL 가져 오기

분류에서Dev

cypress를 사용하여 복잡한 계층 구조에서 요소 가져 오기

Related 관련 기사

  1. 1

    SQL-이 쿼리를 조인하기 위해 다른 테이블에서 열 가져 오기

  2. 2

    조인 쿼리를 사용하여 4 개의 다른 테이블에서 레코드 가져 오기

  3. 3

    다른 테이블의 열 개수 (*)를 참조하여 한 테이블에서 데이터 가져 오기

  4. 4

    조인 및 하위 쿼리를 사용하여 두 테이블에서 행 가져 오기

  5. 5

    다른 테이블 SQL에서 중복 가져 오기 및 열 업데이트

  6. 6

    다른 서버의 SQL 조인 테이블 및 가져 오기 테이블 SSMS

  7. 7

    개발 및 프로덕션 사이트에서 Javascript를 사용하여 다른 기본 URL 가져 오기

  8. 8

    MySQL-조인을 작성하여 다중 계층 연결된 테이블에서 데이터 가져 오기

  9. 9

    사진 참조 및 키를 사용하여 개조 라이브러리를 사용하여 Body 응답에서 사진 가져 오기

  10. 10

    SQL Server 쿼리를 사용하여 출석 로그 테이블 및 직원 테이블에서 null 값을 가져 오나요?

  11. 11

    여러 테이블에서 여러 행 가져 오기 및 하나의 MySQL 쿼리를 사용하여 정렬

  12. 12

    ID를 사용하여 다른 테이블에서 데이터 가져 오기

  13. 13

    TREATAS를 사용하여 다른 테이블에서 측정 값 가져 오기

  14. 14

    JPA를 사용하여 다른 테이블에서 레코드 가져 오기

  15. 15

    쿼리에서 블로그 ID를 사용하여 블로그 카테고리 및 키워드 가져 오기

  16. 16

    계층 구조의 하위 항목이 주어지면 INFORMIX 계층 구조 SQL로 전체 트리를 가져옵니다.

  17. 17

    테이블의 다중 계층 구조에 대한 루트 노드 및 모든 하위 노드를 가져 오는 방법

  18. 18

    SQL 쿼리를 사용하여 데이터 가져 오기 및 Asp의 if 조건

  19. 19

    트리거 삭제 및 다른 테이블에서 필드 가져 오기

  20. 20

    SQL Server에 대한 다른 쿼리에서 사용하기 위해 한 테이블에서 데이터를 가져 오나요?

  21. 21

    SQL : 다른 테이블에서 사용자 정보 및 최신 날짜 기록 가져 오기

  22. 22

    다른 SQL 테이블에서 데이터 가져 오기 및 comboBox에 추가

  23. 23

    함수를 사용하여 뷰 뷰에서 참조하는 테이블 가져 오기

  24. 24

    행 및 열 번호를 사용하여 다른 시트에서 데이터 가져 오기

  25. 25

    mySql (phpMyAdmin)을 사용하여 다른 테이블에서 데이터를 가져 오는 테이블 만들기

  26. 26

    importrange를 사용하여 다른 시트에서 텍스트 및 특정 텍스트 수 가져 오기

  27. 27

    하위 쿼리를 사용하는 동안 다른 테이블에서 이름 가져 오기

  28. 28

    쿼리를 사용하여 HP Vertica에서 테이블 생성 -SQL 가져 오기

  29. 29

    cypress를 사용하여 복잡한 계층 구조에서 요소 가져 오기

뜨겁다태그

보관