一个Select语句,它将执行以下操作

时间:2011-04-13 00:11:50

标签: php mysql

我正在学习如何围绕sql和php。我有4个表格结构如下

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

正如您所看到的,表格通过id一直链接到点,这意味着项目将包含许多包含许多包含多个点的形状的幻灯片。

我有一个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如何与我的算法进行比较?

3 个答案:

答案 0 :(得分:3)

使用像Doctrine之类的ORM,您只需将其建模为

/**
 * @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。

答案 1 :(得分:1)

所以我一直在研究这个问题,然后我想出了自己的答案。我很乐意输入,因为我认为这可能是 BAD 的方式。

这是我的思考过程。一个查询很棒但是如果我们逐步构建结果数组会怎样。我的意思是我们可以通过遍历带有设计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
...

这个解决方案的问题就在我的评论中。我认为您可以使用数组搜索复制这些结果,以查找答案中列出的原始结果。但这似乎更糟糕了。

请为我的生活告诉我如何改进这一点对它的任何评论都会对我有帮助。

非常感谢。

答案 2 :(得分:0)

我希望这有帮助:

<?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。