views:

135

answers:

2

Hi there. I have 4 tables:

categories - id, position
subcategories - id, categories_id, position
sub_subcategories - id, subcategories_id, position
product - id, sub_subcategories_id, prod_pos

Now I'm doing tests to find out what's wrong with my query.

So i want to select sub_subcategories, and to get someting like that:

[[1,2,3,4,5,6], [1,2,3,4,5,6,7]], [[1,2,3,4,5,6], [1,2,3,4]]

Each [] means: big - categories, small - subcategory, and the numbers are position in sub_subcategories. I want the [] to order by their "position" field, so query:

SELECT id FROM sub_subcategories_id 
WHERE subcategories_id IN (
       SELECT id 
       FROM subcategories_id 
       WHERE categories_id IN (
            SELECT id FROM categories 
            WHERE id = 'X' ORDER BY position) 
            ORDER BY position) 
ORDER BY position

is somehow wrong, because I get:

1,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,6,6,6,7

Dunno why - does last "ORDER BY position" destroy everything?

+4  A: 

You need to apply all of your desired ordering in the outermost query - ORDERing within subqueries doesn't make any sense - the question "is this ID in <this list>?" has the same answer, no matter what order the list is in (indeed, more property, <this list> is a set, which has no order).

So you'll need to get all of the columns you need to order by in your outermost query.

Something like:

SELECT ssi.ID
from
    sub_subcategories_id ssi
        inner join
    subcategories_id si
        on
            ssi.subcategories_id = si.id
        inner join
    categories c
        on
           si.categories_id = c.id
where
    c.id = 'X'
order by
    c.position,
    si.position,
    ssi.position
Damien_The_Unbeliever
A: 

As it stands now, your query would never return a 'set' of numbers as is. If you ignore all the subselects, you're essentially doing:

SELECT id FROM sub_subcategories_id 
ORDER BY position

which would only return one column: the sub_sub_categories_id. You'd be better off doing something like:

SELECT cat.id, subcat.id, subsubcat.id
FROM sub_sub_categories AS subsubcat
LEFT JOIN sub_categories AS subcat ON subcat.id = subsubcat.subcategories.id
LEFT JOIN categories AS cat ON cat.id = subcat.category_id
WHERE (cat.id = 'X')
ORDER BY cat.id, subcat.id, subsubcat.id

That'll return 3 columns ordered by the various IDs. If you don't need the individual sub_sub_categories values, and just want them as a single string value, you can mess around with GROUP_CONCAT() and do various bits of grouping:

   SELECT cat.id, subcat.id, GROUP_CONCAT(subsubcat.id)
   FROM ...
   ...
   WHERE (cat.id = 'X')
   GROUP BY cat.id, subcat.id, subsubcat.id
   ORDER BY ...
Marc B