Alessandro Minoccheri
Alessandro Minoccheri

Reputation: 35973

SQL join into join create a good array

Hi I want to make a good query to have a good array. Now for example I have this query:

SELECT DISTINCT * FROM products 
        LEFT OUTER JOIN  product_aliases 
        ON product_aliases.product_id = products.id 
        AND product_aliases.alias = '$alias'
        LEFT OUTER JOIN  (product_images
            LEFT OUTER JOIN  product_image_votes 
                    ON product_image_votes.product_image_id = product_images.id)
        ON product_images.product_id = products.id 
WHERE products.id = $id

The result is two array like this:

array(
(int) 0 => array(
    'products' => array(
        'id' => '1',
        'user_id' => '1',

    ),
    'product_aliases' => array(
        'id' => '1',
        'product_id' => '1',
        'language' => 'it',
    ),
    'product_images' => array(
        'id' => '1',
        'product_id' => '1',
    ),
    'product_image_votes' => array(
        'id' => '2',
        'product_image_id' => '1',
        'vote' => '1',
    )
),
(int) 1 => array(
    'products' => array(
        'id' => '1',
        'user_id' => '1',

    ),
    'product_aliases' => array(
        'id' => '1',
        'product_id' => '1',
        'language' => 'it',
    ),
    'product_images' => array(
        'id' => '1',
        'product_id' => '1',
    ),
    'product_image_votes' => array(
        'id' => '2',
        'product_image_id' => '1',
        'vote' => '1',
    )
)

The problem is that: I want only a unique array that contain product and for example product_images that contain in an array product_images_votes. The first problem is:

Example of array:

array(
(int) 0 => array(
    'products' => array(
        'id' => '1',
        'user_id' => '1',

    ),
    'product_aliases' => array(
        'id' => '1',
        'product_id' => '1',
        'language' => 'it',
    ),
    'product_images' => array(
        'id' => '1',
        'product_id' => '1',
        array('product_image_votes' => array(
            'id' => '2',
            'product_image_id' => '1',
            'vote' => '1',
        ))
    )

Is possible to do ? I'm working with php

Upvotes: 3

Views: 1602

Answers (1)

Michael Berkowski
Michael Berkowski

Reputation: 270607

Your query is good as it is, but you need to construct the nesting in PHP. You cannot really produce nested structures in SQL alone so you must work with the flattened structure as you have it.

This can be done with some creative looping. Create an output array which is indexed by products['id']. On each iteration, create a new entry if it does not already exist. If it does exist, add to its product_images, an array also indexed by product_images['id'].

// To hold the final array
$output = array();
foreach ($original_array as $row) {

  // Storing these id values to make them easier to refer to...
  $id = $row['products']['id'];
  $pid = $row['product_images']['id'];
  $paid = $row['product_aliases']['id'];
  $pivid = $row['product_image_votes']['id'];

  // Create the product entry if it does not exist
  // and initialize arrays for product_images and product_aliases    
  if (!isset($output[$id])) {
    $output[$id] = array(
      'products' => $row['products'],
      // Initialize these to sub-arrays containing the first ones from this row
      // using the id as the array key
      'product_aliases' => array($paid => $row['product_aliases']),
      'product_images' => array($pid => $row['product_images'])
    );
    // Then add the first vote
    $output[$id]['product_images'][$pid]['product_image_votes'] = array();
    $output[$id]['product_images'][$pid]['product_image_votes'][$pivid] = $row['product_image_votes'];
  }
  // If it does exist already, append the alias if that does not exist, the image, the vote etc.
  else {
    // First add the alias if not already set
    if (!isset($output[$id]['product_aliases'][$paid])) {
      $output[$id]['product_aliases'][$paid] = $row['product_aliases'];
    }
    // Then add the image if not already set
    if (!isset($output[$id]['product_images'][$pid])) {
      $output[$id]['product_images'][$pid] = $row['product_images'];
    }
    // And nest in the image_votes
    if (!isset($output[$id]['product_images'][$pid]['product_image_votes'][$pivid])) {
      $output[$id]['product_images'][$pid]['product_image_votes'][$pivid] = $row['product_image_votes'];
    }
  }
}

There's a lot here, and it is likely I have syntax errors or missing ] somewhere. Good luck with it.

Upvotes: 2

Related Questions