Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
ToddW
Starting Member
4 Posts |
Posted - 2005-01-08 : 12:47:24
|
I have a client who wants to put their catalog online. They have different Catagories (ex: Tape, Paper, Stretchwrap) with many Sub-Categories per Catagory (ex: Tape has Security Gummed, Natural Gummed, etc). The problem is that each of these Sub-Categories can have different columns. :-(EX:Security Gummed : Item#, printed message, size, mil, rolls/caseNaturally Gummed: Item#, width, length, strands, rolls/case, colorI would like to have a generic ASP page that would be linked to from a Product Menu that could display which ever Category/Sub-Category the user chooses and display the appropriate columns and column names.Anyone have any thoughts on how to define the table(s) to do this?Thanks in advance for any help :-) |
|
jhermiz
3564 Posts |
Posted - 2005-01-08 : 13:07:35
|
Hey Todd,Although it may seem like seperate sub categories it really is not from a table perspective.You will need a table which links back to itself for instance you mentioned:Tape Security Gummed Natural GummedIn a table valid records would beCategoryID ParentID Product 1 NULL Tape 2 1 Security Gummed 3 1 Natural Gummed.... What you have here is the type of product and it's parent. Some products (the main categories) willnot have a parent associated with them. From a tree perspective, these are your "root pointers" they areat the highest level in the hierarchy. Below the root may be various subcategories...and you can take it furtherthan that. You may have a case where a sub category branches off into many different other sub sub categories.SubCategories-------------CategoryID (ID)ParentID (allow nulls, may be a foreign key from another table - Category)SubCategory (the sub category itself)The parentID is just the key of the parent if one exists1 NULL Tape (Tape in a Category table will be some sort of ID number say 1)If a subcategory has a parent you reference that ID number and you enter the sub category.If you wanted all categories you could do:SELECT SubCategory FROM SubCategory WHERE ParentID IS NULL If you wanted all sub categories:SELECT SubCategory FROM SubCategory WHERE ParentID IS NOT NULL If you wanted a subcategory for a specific category, for instance you wanted all sub categories of the category tape:Assume that tape is in the Cateogry table with CategoryID number = 1--this is in the case that you store the main categories in another tableSELECT SubCategory.SubCategory FROM SubCategory INNER JOIN Category ONCategory.CategoryID = SubCategory.ParentIDWHERE SubCategory.ParentID= 1 This should return:Security Gummed and Natural Gummed provided you have entered these into the table correctly:CategroyID ParentID SubCategory -------- ------------ 1 NULL Tape 2 1 Security Gummed 3 1 Natural Gummed Make sense ?Jon[edit]You have the option of placing the main categories in a seperate table if you want. You can also just keep the main categories in this table and label the ParentID as NULL. If you take this route and you wanted all tape subcategories:SELECT SubCategory FROM SubCategory WHERE ParentID=1 Sorry I had forgotten to mention this from before. So it is upto you whether you need to seperate your main categories from your sub categories. If more information is needed for a particular category than I would normalize it and place it in a seperate table from your sub categories. But if you have no information that you need to store than you could get away with storing it in a single self referencing table.[/Edit] Keeping the web experience alive -- [url]http://www.web-impulse.com[/url] |
 |
|
ToddW
Starting Member
4 Posts |
Posted - 2005-01-08 : 13:49:58
|
Hi Jon,That was quick. Thanks for the reply.Your post cues me in on some things I need to learn but not sure it solves my problem - but I may not understand it.See if this gives you a more information on where I am and what I need (or think I need :-) My initial thoughts were:Have a Category table (Tape, Stretchwrap, Paper, etc) with CategoryID and CategoryName as the 2 columns (I could use this to build a dynamic Product Category menu).Have a SubCategory table (Security Gummed, Natural Gummed, etc) with SubCategoryId, Name and CategoryID (with Referential Integrety enabled so they can't accidentally delete a Category that has a SubCategory). I could use this to build dynamic SubCatgeory fly-out menus.Have an Item table which would have CategoryID, SubCategoryID (with Referential Integrity enabled), and appropriate columns as part of the table.My problem is with the Item table. The items have different attributes (some have Width & Length others have Strands & Rolls per Case). There are 32 possible columns to cover all the items and each item uses some combination of 4-6 of these.Should I put all these in one table and just leave columns null that aren't used? If so, how can the page displaying the data figure out what columns are to be displayed and what the column names are?Is this possible?Should they all be in separate tables? Still, how could 1 generic page figure out how many columns there are and what the column names are?Thank so much for helping.ToddThat's my conundrum. |
 |
|
jhermiz
3564 Posts |
Posted - 2005-01-08 : 16:53:05
|
Ack slow down a bit :)I dont think you need 32 column names and having these as bits checked on our off if it is valid or not.Take a step back and read what I posted. I think you need a table that within this table..references itself.Todd, let me give you an example. Lets say, and I am just guessing here so you can modify to fit your needs, you have a category called cars. Cars can come in all sorts of colors BUT there are specific cars that have 4 wheels as opposed to 3 wheels, some cars have abs others dont, some cars have a stick shift, others dont. So lets look at this in a self referencing table:CategoryID ParentID Item-------------------------------1 NULL Car2 1 Volvo3 1 Mustang4 2 ABS5 2 Air Bags6 2 AWD7 3 Stick Shift8 3 Mach stereo9 3 Air Bags------------------------------------------ What do you see from this. We see a root node called "Car" it branches off into two cars, a Volvo (id=2) and a Mustang (id=3). A volvo and a mustang have different features, sure some features may be the same (they both have air bags, see the table I posted). But a lot of the features cannot be found in common with both vehicles. For instance, notice the volvo has ABS but the Mustang doesnt. Furthermore the mustang has a mach stereo system and the volvo doesnt.My point here is you do not need a table with 'n' columns where n will probably grow...For instance, today you said that there may be 32 columns of things where an item has something while another item might not have that same thing. What happens when your boss says well item x can have attribute y now...and you never defined y ??? You will have to keep putting bandages over a table that is growing constantly.In fact the worst thing to do is to create 32 bit columns in a table and check off what item has what. It is painful, the size of your row grows, updates can be difficult, and its just a lot of work when new attributes are added.Think about my example and tell me what you think. You can even create another sub level table that stores the various categories...Either way using that table I posted If I wanted all the cars I could do:SELECT Item FROM YourTable WHERE ParentID=1result...VolvoMustang If I wanted all the attributes of a volvo:[code]SELECT Item FROM YourTable WHERE ParentID=2 [code]result set...Volvo------ABSAWDAir Bags I can do the same thing for the mustang...and so on and so on.Jon Keeping the web experience alive -- [url]http://www.web-impulse.com[/url] |
 |
|
ToddW
Starting Member
4 Posts |
Posted - 2005-01-08 : 18:08:25
|
Jon,Thanks for your patience, this way of doing it is new to me (as you may have guessed, I'm a multiple tables w/Joins kinda guy).I'm starting to see. Very creative. I think with one last piece it may be solved. The individual item level.Using your example, let's say this company is an Auto Parts Dealer and they sell Air Bags (category) and have air bags for Volvos and Mustangs (sub-category) and they have 3 types of air bags for the Volvo and 3 different types of air bags for the Volvo AND these air bags have different properites (the volvo has item#, width, depth and wheel size and the Mustang has item#, #of screws and diameter). How would that get into the database?Example Result set for display:Air Bags- Volvo - Item#, width, depth, wheel size - 12543, 12, 4, 20 - 12567, 12, 4.5, 20 - 12789, 14, 5, 23 - Mustang - Item#, #of screws, diameter - 14367, 4, 30 - 14368, 5, 32 - 14369, 5, 34Note: and they need to be sorted in ascending order for the appropriate columns for each type of item within the sub-category. How to I specify THAT! argh!It may be less confusing to take a look at the actual site and use real examples if you don't mind: [url]www.pacnetusa.com[/url]The Tape & Strapping categories have the most sub-categories.I was originally thinking to have each sub-category on it's own page (when I was in the dark ages with mulitple tables :-) and the call to the ASP page could specify certain things (ex: list.asp?cID=1,scID=3,sort=x) but it would be nice to keep them on one page as it currently is.Thanks again for your time,Todd |
 |
|
jhermiz
3564 Posts |
Posted - 2005-01-08 : 21:19:48
|
Sorry for taking long to get back to you Todd.I agree you should not have this on different pages, it should be all on one page. In fact you could if you wanted to put all sub categories in a drop down. You select a sub category and it can display its relevant children. Please do not think you are 100% wrong in creating multiple tables, you could do that but your work may easily increase since you are tapping more tables etc...As for your question of how data would go into a database, I will refer back to the referencing table itself. Again using the example like I had done from before lets take your data and enter it into my tableCategoryID ParentID Item Description--------------------------------------------------------------1 NULL Air Bags Main Item2 1 Volvo Car3 1 Mustang Car4 2 12543 Item #5 2 12567 Item #6 3 14367 Item #7 3 14368 Item #8 4 12 Width9 4 4 Depth10 4 20 Size......................... Now look at this carefully...it really becomes a tree with the root node (Air bags) at the highest level (no parent). Below the air bag we branch into the various cars that have air bags (Mustang, Volvo, BTW it is amazing that I was guessing in my previous post about it being a car type business and it ends up being just that). Below the vehicle we have the items that go with the volvo...12543..... And the items that go with the mustang14367....... Below is a split about the attributes of the item (the width, the depth, the wheel size). The great thing about this structure is you can go as far down the level as you want. In fact you can have the volvo have 20 item attributes while the mustang may only have 3.It may help to grab paper and pencil and just sketch the tree out or the rows and point them back to one another you will notice the following:20, 4, 20 (width, depth, size)---> 12543 (the item) ----> Volvo (the vehicle) ----> Air Bags (the parent)That is all those attributes lead all the way back to Air Bags, the parent. Sorting is simple as well, I am not too sure how you want it sorted but you can either sort based on the CategoryID, the ParentID, or your own sort by defining a new field to sort on.I did a system very very similiar to the one you have described except it was in SQL Server. See if this SQL makes any sense:CREATE PROCEDURE select_components_by_conveyor_type @CategoryID bigintASBEGINSET NOCOUNT ONDECLARE @reached TABLE (category bigint, subcategory bigint NOT NULL, UNIQUE(category, subcategory))INSERT INTO @reached VALUES (NULL, @CategoryID) WHILE( @@rowcount > 0) BEGIN INSERT INTO @reached (category, subcategory) SELECT DISTINCT Categories.ParentID, Categories.CategoryID FROM Categories JOIN @reached AS r ON r.subcategory = Categories.ParentID WHERE not exists (select * from @reached r where Categories.CategoryID = r.subcategory and r.Category = Categories.ParentID) ENDSELECT DISTINCT Components.ComponentID, Components.Component, Components.EnglishDescription, Components.GermanDescription, Components.AdditionalInfoFROM Components JOIN CategoriesByComponentType ON Components.ComponentID = CategoriesByComponentType.ComponentIDJOIN @reached AS r ON CategoriesByComponentType.CategoryID= r.subcategory ORDER BY Components.ComponentSET NOCOUNT OFFENDGO This was using a very similiar if not identical (minus the names of the columns) table structure. What it did was it would take in an ID and find all sub levels below it. For instance let us say we have 3-4 combo boxes. The user first selects "Air Bags" I then take that result and pass the ID to the above procedure. What the procedure does is scan the table and find all sub categories of air bags. The sub categories would be placed in the second combo box. These sub categories in this case are:Volvo and Mustang.The user would then select the Volvo or the Mustang (lets say they choose Volve) I would take the ID of that volvo and pass it to the procedure. In return I would get all Items for a volvo. In your case the items 12543,12567,12789. In the third combo box the user would have to select one of these items...doing so would bring back the width, depth, and wheel size.The solution would work for you with a minor bit of effort on your end. All it takes is just rereading these posts and coming up with a similiar schema. As I said you may be able to create another table if you'd like to store ALL sub categories and rather than having "Volvo" or "Mustang" in this items table you would have corresponding ID numbers. In this case you will have to do one more join to this table to grab the text.Really slick solution.I'm done for the night, I hope this made sense. Don't be scared to ask more questions :).Jon Keeping the web experience alive -- [url]http://www.web-impulse.com[/url] |
 |
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2005-01-09 : 08:40:27
|
am i completly missing the point or would all of this be very simpler with many to many relation between Category and Sub-Category. No need for parent child stuff just simple joins.Category -< CategoryToSubCategory >- SubCategoryGo with the flow & have fun! Else fight the flow |
 |
|
jhermiz
3564 Posts |
Posted - 2005-01-09 : 12:34:23
|
What about items that dont have certain attributes?I thought the self referencing table would be simplier :)I think you can get away with either, but I found the self referencing a lot simplier, especially when you have a structurethat sometimes needs a column while other times doesnt. Keeping the web experience alive -- [url]http://www.web-impulse.com[/url] |
 |
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2005-01-09 : 13:04:03
|
items that don't have attribs are not in the middle relation table.Go with the flow & have fun! Else fight the flow |
 |
|
jhermiz
3564 Posts |
Posted - 2005-01-09 : 16:32:36
|
Todd,You could do that as wellCategories----------CategoryIDCategorySubCategories-------------SubCategoryIDSubCategoryCategorySubCategories---------------------CategoryIDSubCategoryIDThe only problem I see with this is a sub sub category :)...how far is too far ?Meaning in your example an item (which is a sub category) may have sub categories beneath that.If you use this approach you would have to make the item a category as well.Jon Keeping the web experience alive -- [url]http://www.web-impulse.com[/url] |
 |
|
ToddW
Starting Member
4 Posts |
Posted - 2005-01-09 : 17:17:44
|
Hi Jon and spirit1,Thanks for your responses to my thread.Jon - if you check out [url]www.pacnetusa.com[/url], you'll see that an item is the lowest level.Example:Tape- Reinforced Gummed-- item# tap1000-- item# tap1001-- etc..- Natural Gummed-- item# tap2001-- etc...Your solution was creative and I understand what you idea was - basically a row for every category name, then sub category name and then for every attribute of every item. Then link them together with parent pointers (so-to-speak). I would have to enforce my own referential integrity which would is not a problem.Spirit1 - My original thought was to have separate tables but I don't see any way to deal with my original problem that sub-categories under a category have different attributes. I could have separate tables for every sub-category but still don't know how 1 generic page could figure out how to display all the different tables. Or 1 big table of items with 32 columns (the total # of different attributes) but how would I figure out which columns are used and as Jon pointed out if a new item is added with a new attribute I would have to update the table to add the new column. If you could give me an example of your idea - using the Tape page of the [url]www.pacnetusa.com[/url] website - that would really help. I'm not sure if I'm having a brain cramp or what. Can't thank you guys enough,Todd |
 |
|
jhermiz
3564 Posts |
Posted - 2005-01-09 : 18:53:44
|
Hi Todd,It comes back to the table that references itself :)...However, you can still get away with the following:Categories----------CategoryIDCategorySubCategories-------------SubCategoryIDSubCategoryCategorySubCategories---------------------CategorySubCategoryIDCategoryID NOT NULLSubCategoryID NOT NULLAttributes-----------AttributeIDAttributeCategorySubCategoryAttributes-------------------------------CategorySubCategoryIDAttributeIDCategory stores your main category. Subcategory table stores all sub categories. CategorySubCategories stores the relation of a subcategory to a main category. Note the ID in this table may not be needed, but you will then have to include both these fields in CategorySubCategoryAttributes table if you do not store a key for this. Attributes will store every attribute in the db (the ID is optional, you could make Attribute unique, however I noticed this is access, and I know how the access folks like ID's :)). The final table stores the key row of CategorySubCategory and the corresponding attribute associated with it. This is a one to many relationship storing the categorysubcategory with all of its attributes. Would work fine....Jon Keeping the web experience alive -- [url]http://www.web-impulse.com[/url] |
 |
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2005-01-10 : 03:33:27
|
well basicaly jon beat me to it :) twice...Go with the flow & have fun! Else fight the flow |
 |
|
|
|
|
|
|