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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
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
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

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
Guy Hengel [angelIII / a3]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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
HTML

From novice to tech pro — start learning today.