Найдите уровень или глубину дочернего элемента в отношении дочернего родителя (модель списка смежности) с помощью PHP

В таблице mysql есть отношение сотрудника и менеджера, которое хранится как модель списка смежности. У сотрудника есть только один менеджер, а у менеджера много сотрудников, если значение менеджера пусто, что означает, что сотрудник без менеджера.

связь

сотрудник (1 к 1) менеджер сотрудник (многие на 1) менеджер

employee      manager   
10            11
15            10
9             15
6              0             

Хочу в менеджера глубину как для

11 depth is 3
for 10 depth is 2 
for 15 depth is 1
for 6 depth is 0 
......
......
.......

Как я могу добиться этого с помощью php ниже, моя неполная логика.

<?php
get_level(11) // 3
get_level(10) // 2
get_level(15) // 1
get_level(6) // 0

function get_level($level){
   $this->db->get_where('manager_user', array('manager_no' => $level))
   ->result_array()
    // logic 
    return no; //3 for 11
}
?>

Может ли кто-нибудь мне в этом помочь. Если кто-нибудь предоставит мне решение с функцией mysql, это также будет полезно для меня данных, хранящихся в многоуровневой иерархии mysql.

Обновлено: я редактирую свой вопрос в соответствии с предложением @sintakonte.

Шаг, предпринятый мной для решения проблемы - сначала я изменил структуру своей таблицы с Модель списка смежности

кому: Модель вложенного множества

после этого этот класс помог мне добиться желаемого результата

Используете переключатель? php.net/manual/en/control-structures.switch.php

Roy Bogado 09.08.2018 10:56

почему 11 должно быть глубиной 3? - не должно быть 11 в столбце сотрудников и связано с менеджером? (по вашему примеру ...)

sintakonte 09.08.2018 15:21

да, я тоже этого не понял. решил, что корреляции нет, и что он просто опубликовал это для хихиканья

Alex 09.08.2018 21:34

@sintakonte - потому что, есть 3 сотрудника под менеджером 11 (10, 15, 9). а 11 родителей будут нулевыми.

ihcc aman 11.08.2018 08:04

@sintakpnte - проверьте это) stackoverflow.com/questions/10688608/…

ihcc aman 11.08.2018 08:27

а что 6? 6 сотрудник без менеджера что ли? если да, то почему это даже в вашей таблице?

sintakonte 14.08.2018 07:09

И следующий вопрос: может ли любой сотрудник иметь более одного менеджера и наоборот? если да, то что произойдет, если 15 - менеджер 10 или 9 - менеджер 11 и т. д., я имею в виду, чувак, ты должен придумать здесь немного больше данных, потому что это очень паршивое описание вопроса;)

sintakonte 14.08.2018 07:17

мой ответ тебе помог?

sintakonte 16.08.2018 13:12

@sintakonte, спасибо за решение. Я считаю, что логики достаточно, но в таблице есть большие данные. Отображается ошибка «Неустранимая ошибка: достигнут максимальный уровень вложенности функции« 256 », прерывание!»

ihcc aman 18.08.2018 07:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
9
169
3

Ответы 3

Простой. Просто используйте оператор switch:

function get_level($level){
  $query = $this->db->get_where('manager_user', array('manager_no' => $level));
  if ($query->num_rows !== 1) {
    return false;  
  }
  $manager_no = intval($query->row()->manager_no);
  switch ($manager_no) {
      default:
          return false;
      case 11:
          return 3;
      case 10:
          return 2;
      case 15
          return 1;
      case 6:
          return 0;
  }
}

Возвращает false, если case не существует или если запрос не возвращает строк. Я также предполагаю, что manager_no уникален.

Также подумайте, что for 6 depth is 0, по вашему мнению, должен быть перевернут, но вы можете понять эту часть.

Я хочу работать с динамическими данными с помощью функции - @Alex

ihcc aman 09.08.2018 13:24

не знаю, что это значит

Alex 09.08.2018 21:33

Данные хранятся Модель смежности в моем примере, почему вы используете случай переключения

ihcc aman 12.08.2018 11:10

Вот решение для динамических данных

function get_level($level){
   $query = $this->db->query('SELECT count(*) as depth FROM manager_user WHERE manager_no > (SELECT manager_no FROM roles WHERE manager_no ='.$level.')');
   $depth = $query->row_array()['depth'];
}

я думаю, это довольно сложная задача, потому что одна проблема - нехватка информации, а другая - построение дерева

В любом случае я попробовал что-то, что должно работать (пожалуйста, внимательно изучите код) - я не уверен, есть ли лучшие концепции, но я думаю, что это хороший

Создайте модель под названием Manageruser_model.php, как показано ниже.

class Manageruser_model extends CI_Model
{

    private $arrFieldsWithKeys = [];

    private function createTree()
    {
        $arrResult = $this->db->get_where('manager_user')->result();
        //in case a manager is no employee - we've to add this one as an employee with manager id 0
        $arrResult = $this->addManagersAsEmployee($arrResult);

        $arrFieldsWithKeys = [];

        foreach($arrResult AS $obj)
        {
            $arrFieldsWithKeys[$obj->employee] = $obj;
            if (!isset($arrFieldsWithKeys[$obj->manager]) && $obj->manager != 0) $arrFieldsWithKeys[$obj->manager] = $obj;
        }

        $arrFoundChilds = [];
        foreach($arrResult AS $obj)
        {
            if (isset($arrFieldsWithKeys[$obj->manager]))
            {
                if (!isset($arrFieldsWithKeys[$obj->manager]->childs)) $arrFieldsWithKeys[$obj->manager]->childs = [];
                $arrFieldsWithKeys[$obj->manager]->childs[] = $obj;
                $arrFoundChilds[] = $obj->employee;
            }
        }

        $this->arrFieldsWithKeys = $arrFieldsWithKeys;

        $arrRemovedChildsFromMasterNode =array_diff_key($arrFieldsWithKeys,array_flip($arrFoundChilds));
        $this->setTreeDepth($arrRemovedChildsFromMasterNode);

    }

    private function addManagersAsEmployee($arrResult)
    {
        $employees = array_column($arrResult, 'employee');
        $manager = array_column($arrResult, 'manager');
        $arrMissingManagersAsEmployee = array_diff($manager, $employees);
        foreach($arrMissingManagersAsEmployee AS $strId)
        {
            if ($strId > 0)
            {
                $obj = new stdClass();
                $obj->employee = $strId;
                $obj->manager = 0;
                $arrResult[] = $obj;
            }
        }
        return $arrResult;
    }

    private function setTreeDepth($arr)
    {
        $level = 0;
        foreach($arr AS $obj)
        {
            if (isset($obj->childs))
            {
                $level = $this->setTreeDepth($obj->childs);
                $obj->level = $level;
            }
            else
            {
                $obj->level = 0;
            }
        }
        return $level + 1;
    }

    public function getDepth(int $id)
    {
        if (empty($this->arrFieldsWithKeys))    $this->createTree();
        if (!isset($this->arrFieldsWithKeys[$id]))  throw new Exception($id.' doesn\'t exist.');

        return $this->arrFieldsWithKeys[$id]->level;
    }
}

и теперь в вашем контроллере вы можете просто загрузить модель и получить взамен глубину, например

$this->load->model('Manageruser_model');
echo $this->Manageruser_model->getDepth(11);

Другие вопросы по теме