具有多个表的内部联接

时间:2012-08-27 17:48:18

标签: sql join foreign-keys relational-database 3nf

我有这四个表:

PRODUCTS
---------
PRODUCT_ID
PRODUCT_TITLE
(other fields)

COLORS
---------
COLOR_ID
COLOR_NAME

MATERIALS
---------
MATERIAL_ID
MATERIAL_NAME

IMAGES
---------
IMAGE_ID
BIG
MED
SMALL
THUMB

SIZE
---------
SIZE_ID
SIZE_NAME

还有:

PRODUCT_COLOR
---------
PRODUCT_ID
COLOR_ID

PRODUCT_MATERIAL
---------
PRODUCT_ID
MATERIAL_ID

PRODUCT_SIZE
---------
PRODUCT_ID
SIZE_ID

PRODUCT_IMAGE
---------
PRODUCT_ID
IMAGE_ID
COLOR_ID (can be null)
MATERIAL_ID (can be null)

所有产品都可以有不同的颜色和/或材料。例如。我可以有一个产品有一个或多个材料选项但没有颜色关联,反之亦然。输出应该是这样的:

-----------------------------------------------------------------------------
| PRODUCT_ID | PRODUCT_NAME  | COLOR_ID | MATERIAL_ID | IMAGE_ID | SIZE_ID |
-----------------------------------------------------------------------------
| 1          | T-SHIRT       | 1        | null        | 1        | 1        |
| 1          | T-SHIRT       | 1        | null        | 1        | 2        |
| 1          | T-SHIRT       | 1        | null        | 1        | 3        |
| 1          | T-SHIRT       | 1        | null        | 1        | 4        |
| 2          | JEANS         | null     | 1           | 2        | 1        |
| 2          | JEANS         | null     | 1           | 2        | 2        |
| 2          | JEANS         | null     | 1           | 2        | 3        |
| 2          | JEANS         | null     | 1           | 2        | 4        |
| 2          | JEANS         | null     | 1           | 2        | 5        |
| 3          | T-SHIRT VNECK | 2        | 2           | 3        | 1        |
| 3          | T-SHIRT VNECK | 2        | 2           | 3        | 2        |
| 3          | T-SHIRT VNECK | 3        | 2           | 4        | 1        |
| 3          | T-SHIRT VNECK | 3        | 2           | 4        | 2        |
| 3          | T-SHIRT VNECK | 4        | 3           | 5        | 1        |
| 3          | T-SHIRT VNECK | 4        | 3           | 5        | 2        |
-----------------------------------------------------------------------------

我尝试了以下语句,但它返回0行:

SELECT PRODUCTS.PRODUCT_ID, PRODUCTS.PRODUCT_TITLE, COLORS.COLOR_ID, MATERIALS.MATERIAL_ID, IMAGES.IMAGE_ID, SIZE.SIZE_ID from PRODUCTS
    INNER JOIN PRODUCT_COLOR ON (PRODUCTS.PRODUCT_ID = PRODUCT_COLOR.PRODUCT_ID)
    INNER JOIN COLORS ON (COLORS.COLOR_ID = PRODUCT_COLOR.COLOR_ID)
    INNER JOIN PRODUCT_MATERIAL ON (PRODUCTS.PRODUCT_ID = PRODUCT_MATERIAL.PRODUCT_ID)
    INNER JOIN MATERIALS ON (MATERIALS.MATERIAL_ID = PRODUCT_MATERIAL.MATERIAL_ID)
    INNER JOIN PRODUCT_IMAGE ON (PRODUCTS.PRODUCT_ID = PRODUCT_IMAGE.PRODUCT_ID)
    INNER JOIN IMAGES ON (IMAGES.IMAGE_ID = PRODUCT_IMAGE.IMAGE_ID)
    INNER JOIN PRODUCT_SIZE ON (PRODUCTS.PRODUCT_ID = PRODUCT_SIZE.PRODUCT_ID)
    INNER JOIN SIZE ON (SIZE.SIZE_ID = PRODUCT_SIZE.SIZE_ID)
    ORDER BY PRODUCTS.id_PRODUCT;

有什么想法吗?

3 个答案:

答案 0 :(得分:20)

你可以这样做:

select p.product_id,
  p.product_name,
  c.color_id,
  m.material_id,
  i.image_id,
  s.size_id
from products p
left join product_color pc
  on p.product_id = pc.product_id
left join colors c
  on pc.color_id = c.colorid
left join product_material pm
  on p.product_id = pm.product_id
left join materials m
  on pm.material_id = m.material_id
left join product_image pi
  on p.product_id = pi.product_id
left join images i
  on pi.image_id = i.image_id
  or c.color_id = i.color_id
  or m.material_id = i.material_id
left join product_size ps
  on p.product_id = ps.product_id
left join size s
  on ps.size_id = s.size_id

我建议你复习JOIN。有一个很棒的visual explanation of joins在线可以帮助您编写这些查询。

答案 1 :(得分:3)

嗯,你需要学习如何构建连接,而我通常这样做的方法是选择一个表并加入下一个表,然后连接下一个表和下一个表,直到得到我想要的结果。

select product_id, product_name
  from products

接下来我加入我需要的第一个,所以我继续说

select p.product_id, p.product_name, pc.color_id
  from products p
  join product_color pc on (pc.product_id = p.product_id)

在加入时,重要的是弄清楚我是否可能没有任何东西可以加入,我仍然希望看到这一行。所以我宁愿使用左连接

     select p.product_id, p.product_name, pc.color_id
       from products p
  left join product_color pc on (pc.product_id = p.product_id)

这样你就可以添加每个表来加入。顺便说说。这是家庭作业吗?

答案 2 :(得分:0)

如果您只需要ID,请保持简单

select p.product_id,
  p.product_name,
  pc.color_id,
  pm.material_id,
  pi.image_id,
  ps.size_id
from products p, 
PRODUCT_COLOR pc, 
product_material pm, 
PRODUCT_SIZE ps, 
PRODUCT_IMAGE pi
where 
p.product_id = pc.product_id(+)
and p.product_id = pm.product_id(+)
and p.product_id = ps.product_id(+)
and p.product_id = pi.product_id(+);