2014-03-27 37 views
0

我試圖列出所有銷售包含吉他裝備的特定吉他部件的產品的商店。MySQL:通過多個表引用時返回多於一行

我有一個guitarRig數據庫。吉他鑽機具有parts(即amplifiercabinetmicrophoneguitarTypeguitarStringTypepatchCordeffectsPedal),它來自於產品,這是從商店購買。 產品的購買價格由我的PurchaseInformation表格決定。

這裏是我的表:

Table Part: 
    name 
    guitarRig references GuitarRig(name) 
    product references Product(name) 

Table Product: 
    name 
    part references Part(name) 
    barcodeNumber 

Table PurchaseInformation: 
    price 
    product references Product(name)  
    purchasedFrom references Store(name) 
Table Store: 
    name 
    storeLocation 

到目前爲止,我已經是這樣的:

SELECT p.name AS Part, prod.name AS Product, sto.name AS Store 
FROM Part p, ProductInformation prod, Store sto, PurchaseInfo purch 
WHERE sto.storeNumber = purch.storeNumber 
    AND purch.product = prod.name 
    AND prod.Part = p.name 
    AND p.name = 
    (
     SELECT name 
     FROM Part 
     WHERE name LIKE '%shielded%' 
    ) 
GROUP BY p.name; 

我得到的錯誤然而,它返回超過1行,這是我想要的!我想列出銷售包含我正在搜索的零件的產品的商店。

回答

1

快速修復是用IN運算符替換相等比較運算符(=)。

AND p.name IN 
    (
     SELECT name ... 

我說這是速戰速決,因爲這會修正這個錯誤,但是這是不寫查詢的最有效方法。並不清楚你的查詢將返回你指定的結果集或實際期望的結果集。

我強烈建議您避免舊學校逗號加入運算符,並使用JOIN關鍵字代替。

重新構建您的查詢成等價的查詢產生這樣的:

SELECT p.name AS Part 
    , prod.name AS Product 
    , sto.name AS Store 
    FROM Part p 
    JOIN ProductInformation prod 
    ON prod.Part = p.name 
    JOIN PurchaseInfo purch 
    ON purch.product = prod.name 
    JOIN Store sto 
    ON sto.storeNumber = purch.storeNumber 
WHERE p.name IN 
     (
     SELECT name 
      FROM Part 
      WHERE name LIKE '%shielded%' 
     ) 
GROUP BY p.name; 

的一些注意事項。 GROUP BY子句將爲每個不同的零件名稱將所有連接的行摺疊爲一行。也就是說,您只會爲每個零件名稱返回一行。

這聽起來不像你想要的那樣。我建議你刪除那個GROUP BY,並添加一個ORDER BY,至少在找出你得到的結果集,以及這是你想返回的行之前。

其次,使用IN (subquery)不是最有效的方法。如果p。名稱匹配由子查詢返回的值,因爲p是相同的Part表的引用,這樣的:

WHERE p.name IN 
     (
     SELECT name 
      FROM Part 
      WHERE name LIKE '%shielded%' 
     ) 

實際上只是一種說法,這更復雜的方法:

WHERE p.name LIKE '%shielded%' 

我想你真的想要更像這樣的東西:

SELECT p.name  AS Part 
    , prod.name AS Product 
    , sto.name AS Store 
    FROM Part p 
    JOIN ProductInformation prod 
    ON prod.Part = p.name 
    JOIN PurchaseInfo purch 
    ON purch.product = prod.name 
    JOIN Store sto 
    ON sto.storeNumber = purch.storeNumber 
WHERE p.name LIKE '%shielded%' 
ORDER BY p.name, prod.name, sto.name 

那將返回來自Part的所有行,其中包含名稱中某處的字符串'屏蔽'。

我們打算將這些行匹配到ProductInformation中匹配該部分的所有行。 (請注意,對於內部聯接,如果PartProductInformation中沒有至少一個匹配的行,則不會返回來自Part的那一行,它只會返回在ProductionInformation中至少找到一個「匹配」行的行。

同樣,我們加入到PurchaseInfo中的匹配行中,然後加入到Store中。再一次,如果至少有一個Store中沒有匹配的行,我們將不會返回這些行。至少與Store有關。我們不會收回任何不在StorePart

行可以返回任何orde r,所以爲了使結果集具有確定性,我們可以添加一個ORDER BY子句。這不是必需的,它不影響返回的行,它隻影響返回行的順序。