Order by column with multiple values

I have a products table in my db which has a category field which relates to another table.

For example:

prodId   prodName   prodCat
1            test              2
2            test 2           2
3            test 3           1
4            test 4           1
5            test 5           2

The category table has id, name and order:

catID   catName   catOrder
1         cat1           3,4
2         cat2           1,2,5

The catOrder field is just a collection of the product ID's, what I want is to display the products table but in the order which appears in the catOrder column.

I currently have the following in my SQL:

SELECT store.*, cat.* FROM (store LEFT JOIN cat ON store.prodCat = cat.catID) WHERE store.prodCat = '" . $_GET['cat'] . "'

How would I go about splitting the catOrder field so that I can order by this field?

Thanks,

Chris
djfenomAsked:
Who is Participating?
 
Guy Hengel [angelIII / a3]Connect With a Mentor Billing EngineerCommented:
this should do (untested ...)
SELECT s.*, c.* , p.*
FROM store s
LEFT JOIN cat c
  ON s.prodCat = c.catID
LEFT JOIN Product p
  ON p.prodcat = c.catid
WHERE s.prodCat = '" . $_GET['cat'] . "'
ORDER BY INSTR( CONCAT(',', c.catOrder,',') , CONCAT(',', p.ProdID, ',') ) 

Open in new window

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_instr

but I agree that the design is bad ...
0
 
Gurvinder Pal SinghCommented:
Or you can update your table structure in this way

prodId   prodName   prodCat   order
1            test              2              1  
2            test 2           2              2
3            test 3           1              1
4            test 4           1              2
5            test 5           2              3

which will make your sql query quite simple, isn't it?
0
 
djfenomAuthor Commented:
Unfortunately the tables are already in place and there are multiple categories which need an order for each one, the only way this would work is if there was a column for each category but this isn't feasible as there is an indefinite number.
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

 
Gurvinder Pal SinghCommented:
Not sure, if there is a way to do it through a query. You will have to get the column value, split the same, and then fetch the products details for an id after iterating through all the id.
0
 
johanntagleCommented:
You need to rearchitecture the database.  The way to properly handle multiple related values is to put it to a seperate table.  Something like a category_orders table the has catID and catOrder as columns, and you have one row each for every CatID-catOrder combination.  Then you can just join this table to your query.
0
 
Ray PaseurCommented:
Unfortunately the tables are already in place
Not really a problem.  You can change data base tables easily with ALTER TABLE.  In this case you should change the tables.  Going forward, you will never again want to have more than one data element in each cell.
0
 
jrm213jrm213Commented:
I am not saying this is efficient, just that it should work for what you want. A lot of times reworking a database after an entire system is in place is just not useful or possible especially if it was a purchased system and changing it will affect other purchased software that runs off of it.

If this is a case of a system currently being developed or one that you or your company has permission to modify then you should try to normalize your database to at least 3rd normal form so you don't run into these problems in the future.


To handle your current situation if my hands were completely tied against changing the database, I would do something like the following

 I am going to make a few assumptions in this

1. you are using mysql_query to access your database
2. you don't want to be hacked via url parameters

also, this is off the top of my head and not tested.


$catId = mysql_real_escape_string($_GET['cat']);
$strSQL = "SELECT store.*, cat.* FROM (store LEFT JOIN cat ON store.prodCat = cat.catID) WHERE store.prodCat = '$catId'";

$result = mysql_query($strSQL);

if(mysql_num_rows($result)>0)
{
        $row = mysql_fetch_array($result);
        $ordervals = $row['catOrder'];
        $order = explode(",",$ordervals);
         mysql_data_seek($result,0); 
}

//you now have an array that denotes the order to display your fields.
$index = 0;
while($row = mysql_fetch_array($result))
{
     if($index < mysql_num_rows($result))
    {
         if($row['prodId'] == $order[$index])
         {
               //add code here to display your data
               $index++;  
               mysql_data_seek($result,0);  //set mysql result pointer back to beginning
     }
 }

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.