Подтвердить что ты не робот

Выбирать выражение, которое будет делать следующее

Я просто изучаю, как обернуть голову вокруг sql и php. У меня есть 4 таблицы, структурированные следующим образом

+-----------+    +------------+    +---------+    +----------+
|  Project  |    | Slide      |    | Shape   |    |  Points  |
+-----------+    +------------+    +---------+    +----------+
|    id     |    |  id        |    | id      |    | id       |
+-----------+    | project_id |    | cont_id |    | shape_id |
                 +------------+    +---------+    | x        |
                                                  | y        |
                                                  +----------+

Как вы можете видеть, таблицы привязаны идентификатором вплоть до точек, означающих, что проект будет содержать несколько слайдов, которые содержат несколько фигур, которые содержат несколько точек.

У меня есть SQL-запрос

SELECT slide.`id`, shape.`id`, points.`x_point`, points.`y_point` 
FROM `project`, `slide`, `shape`, `points` 
WHERE 1 = slide.`project_id` 
   AND slide.`id` = shape.`slide_id` 
   AND shape.`id` = points.`shape_id`

Я хочу, чтобы результаты этого запроса выглядели следующим образом:

[0] => stdClass Object
     (
         [id] => 27
         [x] => 177
         [y] => 177
     )

 [1] => stdClass Object
     (
         [id] => 27
         [x] => 178
         [y] => 423
     )

 [2] => stdClass Object
     (
         [id] => 27
         [x] => 178
         [y] => 419
     )

 [3] => stdClass Object
     (
         [id] => 27
         [x] => 178
         [y] => 413
     )

 [4] => stdClass Object
     (
         [id] => 27
         [x] => 181
         [y] => 399
     )

 [5] => stdClass Object
     (
         [id] => 27
         [x] => 195
         [y] => 387
     )

 [6] => stdClass Object
     (
         [id] => 27
         [x] => 210
         [y] => 381
     )

 [7] => stdClass Object
     (
         [id] => 27
         [x] => 231
         [y] => 372
     )

 [8] => stdClass Object
     (
         [id] => 27
         [x] => 255
         [y] => 368
     )

 [9] => stdClass Object
     (
         [id] => 27
         [x] => 283
         [y] => 368
     )
... AND CONTINUED FOR A LONG TIME

Я хочу преобразовать этот зверский массив дерьма во что-то более похожее на это

[9] => stdClass Object
         (
             [id] => ID OF LIKE SHAPES
             [x] => Array(ALL THE X POINTS)
             [y] => ARRAY(ALL THE Y Points)
         )

Я не могу за всю жизнь понять, как преобразовать это в такой массив.

Если это не может быть сделано с запросом, который я разработал, есть лучший запрос. Возможно, тот, который захватывает точки, затем берет, что помещает его в массив из точек... Я думаю, что у меня просто появилась идея...


Новая информация,

Итак, я добавил ответ на этот вопрос, я не знаю, стандартный ли это. Чтобы помочь другим ответам, если мое не является хорошим решением, я также добавлю свой мыслительный процесс.

Посмотрите мой ответ ниже для получения дополнительной информации.

Также как ORM сравнивается с моим алгоритмом ниже?

4b9b3361

Ответ 1

Используя ORM, например Doctrine, вы просто моделируете его как

/**
 * @Entity
 */
class Project
{
    /**
     * @Id @GeneratedValue
     * @Column(type="integer")
     */
    private $id;

    /**
     * @OneToMany(targetEntity="Slide", mappedBy="project")
     */
    private $slides;

    public function __construct()
    {
        $this->slides = new \Doctrine\Common\Collections\ArrayCollection;
    }
}

/**
 * @Entity
 */
class Slide
{
    /**
     * @Id @GeneratedValue
     * @Column(type="integer")
     */
    private $id;

    /**
     * @ManyToOne(targetEntity="Project", inversedBy="slides")
     * @JoinColumn(name="project_id", referencedColumnName="id")
     */
    private $project;

    /**
     * @OneToMany(targetEntity="Shape", mappedBy="slide")
     */
    private $shapes;
}

И так далее...

См. http://www.doctrine-project.org/docs/orm/2.0/en/reference/association-mapping.html#one-to-many-bidirectional

Разумеется, там задействован большой объем средств для настройки и обработки, но вы оцените ORM, поскольку ваша модель домена становится более сложной.

Ответ 2

Итак, я работал над этим некоторое время, и я придумал свой собственный ответ. Мне бы очень понравился вход, потому что я думаю, что это, вероятно, ДЕЙСТВИТЕЛЬНЫЙ способ сделать это.

Вот мой мыслительный процесс. Один запрос большой, но что, если мы построим массив результатов постепенно. Я имею в виду, что мы можем построить массив результатов, пройдя через таблицы с помощью разработанных операторов SELECT.

Вот код, который я комментирую, потому что мне сложно описать свой алгоритм только словами.

/*  $cur_project is set above from an input value. Assume any int
    The algoritim Traverses a series of results and puts them into the proper places in a usable array.
    The algorithim has an query count of NumberOfSlides + 2(NumberOfSlides)+1 which seems really high
    For real word application if querying the DB is as bad as everyone says.
*/
// A blank array to build up
$projectArray = Array();

// I just want to see how many queries this thing generates
$queryCount = 0;

// Query 1 - This query will get all slides in a project.
$slide_id = $this->db->query('SELECT slide.`id` 
                                FROM `slide`
                                WHERE slide.`project_id` = '.$cur_project);
$queryCount++;

//Now traverse the results to Query 1
foreach ($slide_id->result() as $slide_id){
    // In the project array add an element with the key that is
    // the slide_id for all slides in that project.  Then for each
    // key also create a new empty array at each added element
    $projectArray[$slide_id->id] = Array();

    // Query 2 - grab all the shapes that match the current slide in the current project!
    // This is where things get inefficient.
    $shape_id = $this->db->query('SELECT shape.`id`
                                    FROM `shape`
                                    WHERE shape.`slide_id` = '.$slide_id->id
                                );
    $queryCount++;

    // Traverse the results to Query 2
    foreach ($shape_id->result() as $shape_id) {
        // For every slide now create a key that matches the shape and fill that array with 
        // info I need such as an array of the points.
        $projectArray[$slide_id->id][$shape_id->id] = Array(
                                            'x_points' => Array(), 
                                            'y_points' => Array()
                                        );
        // Query 3 - Ask the DB for x/y points for the current shape. You can see how for slides with lots of shapes
        $points = $this->db->query('SELECT points.`x_point`, points.`y_point` 
                                    FROM `points` 
                                    WHERE points.`shape_id` = '.$shape_id->id
                                );
        $queryCount++;
        // Traverse the Query 3 results
        foreach ($points->result() as $point) {
            // Populate the final arrays with the points
            $projectArray[$slide_id->id][$shape_id->id]['x_points'][] = $point->x_point;
            $projectArray[$slide_id->id][$shape_id->id]['y_points'][] = $point->y_point;

        }
    }
}

Приведенный выше возвращает массив, который выглядит так

Array
(
    [1] => Array
        (
            [27] => Array
                (
                    [x_points] => Array
                        (
                            [0] => 177
                            [1] => 178
                            [2] => 178
                            [3] => 178
                            [4] => 181
...

Что можно интерпретировать как

Array
(
    [SLIDE_ID] => Array
        (
            [SHAPE_ID] => Array
                (
                    [x_points] => Array
                        (
                            [0] => 177
                            [1] => 178
                            [2] => 178
                            [3] => 178
                            [4] => 181
...

Моя проблема с этим решением - это то, что я говорю в своем верхнем комментарии. Я думаю, вы могли бы дублировать эти результаты с помощью поиска массива исходных результатов, указанных в ответе. Это кажется еще хуже.

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

Большое спасибо.

Ответ 3

Я надеюсь, что эта помощь:

<?php
$newStdClass['id'] = $stdClass[$i]['id'];
for($i=0;$i<count($stdClass);$i++)
 {
  $newStdClass['x'][] = $stdClass[$i]['x'];
  $newStdClass['y'][] = $stdClass[$i]['y'];   
 }
?>

Предполагая, что $sttClass - ваш массив дерьма, как вы сказали: D.