Can you do an "intra-table join"?

I've inherited a table that contains a list of products. For the sake of simplicity, we'll say the columns are as follows:

ID (the auto-incremented value)
name
description
size
subsetOf
price

The field subsetOf can either be a number that is 0, meaning it's a "base" product, or some other integer, referring to another ID. If it's not 0, it contains a different size and price from the base product with a blank name and description (since those fields should be the same as the base.)

If this were in two separate tables, you could obviously do a join on subsetOf = ID and not have the name or description fields in the second table at all. As it stands, if I do a query for a couple of IDs I may wind up with the following:

ID   name          description             size   subsetOf   price
3    green shirt   a nifty green shirt     L      0          5.00
4                                          XL     3          9.00

Open in new window


Is there a way within the query to get instead:
ID   name          description             size   subsetOf   price
3    green shirt   a nifty green shirt     L      0          5.00
4    green shirt   a nifty green shirt     XL     3          9.00

Open in new window


Thanks!
SiobhanElaraAsked:
Who is Participating?
 
Ray PaseurConnect With a Mentor Commented:
You almost certainly want to redesign the data base with the help of a professional DBA.

Each table.column should have a unique meaning.  The SKU would be different for shirts of different sizes, and since inventories are managed and orders are fulfilled by SKU, it should be present as a canonical element in the article identity, and that means it should be in each row of the table.  There is really no advantage at all to omitting the name and description in rows of similar products.   The ambiguity you describe will lead to all sorts of programming headaches and may make reporting and inventory difficult.  

Make a Google search for the exact phrase Should I Normalize my Database and read the very good arguments on both sides of the question.  The takeaway message is this: Each row of the table should describe one item that is in the inventory.  A separate table should contain the count of items that are available for sale, and they should be joined via the SKU.
0
 
Kent OlsenConnect With a Mentor Data Warehouse Architect / DBACommented:
Hi Elara,

There are a lot of ways (and reasons) to join tables to themselves.  In your case you probably want something like:

SELECT *
FROM mytable t0
LEFT JOIN mytable t1
  ON t0.id = t1.subsetof

There are potential difficulties though.  If you've got more than one row with a value of subsetof that matches a key, do you want both of those rows to show up (as separate rows) or do you have a means of determining which row to choose?


Kent
0
 
SiobhanElaraAuthor Commented:
Thank you, Kent! That's pretty much what I was looking for, though I've run into an issue with the execution. This is my actual query:

SELECT t1.product_ID, t2.name, t2.description, t2.size, t2.quantity, t1.price, t1.SKU
FROM tbl_products t1
LEFT JOIN tbl_products t2
ON t1.subset_of = t2.product_ID
      WHERE t1.product_ID = <cfqueryparam value="#SESSION.cart[x].product_ID#" cfsqltype="cf_sql_integer">

This works great provided the item has a subset_of that's not 0. If it's 0, I lose the t2 values because there's obviously no product_ID of 0. Is there a way to "pre-check" if t1.subset_of is 0, or am I going about this entirely wrong?
0
 
Kent OlsenData Warehouse Architect / DBACommented:
When the t2 values are null, you just use the t1 values.

A query to put them into a single column is a bit more complex, but it can certainly be done.


Kent
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.