2013-01-10 94 views
0

我有以下的數據庫結構:如何合併兩個表格?

`Products` 
------------------------------------- 
ID | ProductNo 
------------------------------------- 
1 | 3340 
2 | 3450 


`ProductVariants` 
------------------------------------- 
ID | MasterID (ref to `Products`.`ID`) | ProductNo 
------------------------------------- 
1 | 1 | 3341 
2 | 1 | 3342 
3 | 2 | 3451 

我如何獲得產品和他們的產品有一個查詢異體?

編輯:

期望的結果:

MasterID | IsMaster | ProductNo | VariantProductNo 
1 | 1 | 3340 | null 
1 | 0 | 3340 | 3341 
1 | 0 | 3340 | 3342 
2 | 1 | 3450 | null 
2 | 0 | 3450 | 3451 

回答

1

這將做到這一點

SELECT * 
FROM Products 
INNER JOIN ProductVariants 
ON Products.ID = ProductVariants.MasterID 

通常與效率的單個查詢完成(你可以在有一個查詢產品表,循環的結果,併爲每一個在ProductVariants表上做一個查詢,但它會是狗慢)。

你可以使用LEFT OUTER JOIN代替,如果你想爲哪個有產品沒有變種

當您更新的要求走,像這樣(沒有測試過,所以藉口任何錯別字)

SELECT Products.MasterID, 1 AS IsMaster, Products.ProductNo, NULL AS VariantProductNo 
FROM Products 
UNION 
SELECT Products.MasterID, 0 AS IsMaster, Products.ProductNo, ProductVariants.VariantProductNo 
FROM Products 
INNER JOIN ProductVariants 
ON Products.ID = ProductVariants.MasterID 
ORDER BY MasterID, IsMaster DESC, ProductNo 
+0

這將做到這一點!這是一個好方法還是可能會減慢執行查詢? – frgtv10

+0

我想不出一個更有效的方法來做到這一點(有人可能知道的方式)。使用UNION ALL而不是UNION可以提高效率(一個普通的UNION消除了需要一些額外處理來檢查的副本,而在這種情況下,由於IsMaster字段不會有任何重複)。此外,它依賴VariantProductNo是唯一的(如果不從產品變體中帶回ID,並且在查詢的第一部分中有匹配的空字段)。 – Kickstart

3

你將要加入的兩個表對他們Id = MasterId

select * 
from products p 
left join ProductVariants v 
    on p.id = v.Masterid 

SQL Fiddle with Demo

一個LEFT JOIN將返回所有即使他們是productsProductVariants表中沒有相應的記錄。

INNER JOIN將返回出現在兩個表中的記錄。

以下是有助於學習連接語法的visual explanation of joins

如果你有多個表的加盟,那麼你可以使用:

select * 
from products p 
left join ProductVariants v 
    on p.id = v.Masterid 
left join MasterArtikel m 
    on v.MasterId = m.MasterId -- you place the columns that join the tables here 
+0

謝謝你的幫助。但是,如果我現在要數這個,我需要添加一個,因爲MasterArtikel缺失。怎麼做? – frgtv10

+0

@ frgtv10查看我的編輯,您將只添加另一個連接幷包含連接表的列名。 – Taryn

+0

也許我誤解了你,但是我想要一個'Product'的結果行,然後爲每個'ProductVariant'得到一個結果行......如何得到它? – frgtv10