Выбирать выражение, которое будет делать следующее
Я просто изучаю, как обернуть голову вокруг 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 сравнивается с моим алгоритмом ниже?
Ответы
Ответ 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.