2013-06-05 100 views
3

我習慣於創建基本查詢,所以我被困在一個相當複雜的問題上。排除SQL查詢結果 - 單表

Order Number Order Line Package Part Number Size Cost Reviewed 
    0001    1   1   A1   S  22.5  Yes 
    0001    1   1   B2   M  33.1  Yes 
    0001    1   1   C3   L  11.2  Yes 
    0001    1   2   A1   XL  15.0  Yes 
    0001    1   3   A2   M  12.0  Yes 
    0001    2   1   D1   S  42.9  Yes 
    0002    1   1   B4   L  72.5  No 
    0002    1   2   A7   XXL  66.7  No 
    0002    2   1   C1   XL  11.8  Yes 
    0002    2   1   B1   S  22.3  Yes 
    0003    1   1   A1   L  55.2  Yes 

我想選擇訂單號,訂單號線和包裝。我必須按部件號,尺寸,成本進行搜索,並且如果它已被審覈。這個表有大約30,000個訂單,所以有多個結果(這是我想要的)。我得到了簡單的部分,並且它能正常工作。例如:

SELECT 
ORDER Number, 
ORDER Line, 
     Package 
FROM TABLE 
WHERE (Part Number='A1' 
     AND SIZE='S' 
     AND Cost='22.5' 
     AND Reviewed='Yes') 
GROUP BY ORDER Number, 
     ORDER Line, 
     Package 
HAVING count(ORDER Number)=1 


Order Number Order Line Package 
    0001    1   1 

這是我的挑戰。我必須排除具有訂單行的結果,其中包<> 1.因此,我上面的示例的結果將被排除,因爲對於訂單號0001 - 訂單行1包含2和3的包。應用此排除時,在我提供的應該是表中唯一有效的結果...

Order Number Order Line Package 
    0001    2   1 
    0002    2   1 
    0003    1   1 

不要擔心空值。性能是一個值得關注的問題(顯然),因爲它是一張大桌子。我環顧四周,但我還沒有找到任何可靠的解決方案。您的指導將不勝感激。

+2

什麼RDBMS和版本您使用的(是Oracle 11g,SQL Server 2008中,MySQL的....)請告訴我們 – Lamak

+0

@約翰ķ你爲什麼不只是使用過濾掉那些行哪裏有條件? –

回答

3

這樣就可以排除與記錄匹配的ORDER_NUMBER和ORDER_LINE有其他的包比1:

SELECT 
    ORDER_Number, 
    ORDER_Line, 
    Package 
FROM 
    aTABLE 
WHERE NOT EXISTS (SELECT 1 
        FROM atable AS b 
        WHERE atable.order_number = b.order_number 
          AND atable.order_line = b.order_line 
          AND b.Package != 1) 
GROUP BY ORDER_Number, 
    ORDER_Line, 
    Package 
+0

感謝您的回覆@Joe,但是當我執行此查詢時,我沒有收到任何結果。我認爲這可能會丟失一些東西,但我將不得不進一步研究。 –

+0

@JohnK這個輸出與我的問題輸出相同。使用此邏輯時,結果集中有哪些不正確的內容?這裏是Joe的版本http://sqlfiddle.com/#!6/3a350/28/0 – Jerry

+0

小提琴對不起,我的查詢中有一個輸入錯誤,我通過你的邏輯創建了這個錯誤,但是給了我0個結果。我只是再次檢查。你的邏輯是正確的,並且非常有幫助。謝謝@Joe和Jarek。 –

1

這可能有點不好,並且不會有很好的表現,但我之前使用過類似的東西。

SELECT ORDERNumber, 
     ORDERLine 
FROM orders 
GROUP BY ORDERNumber, 
     ORDERLine 
HAVING SUM(CASE WHEN package = 1 THEN 0 ELSE 1 END)= 0 
ORDER BY ordernumber, 
     orderline 

sqlFiddle

當部分應在整個MySqlSqlServer,和Oracle是常見的情況。

+0

@meewoK如果包含一個包<>,他不需要訂單行的一個實例。1.一個訂單分成幾行,按照看起來的訂單行分組,每個訂單行可以附加多個包。 – Jerry

+0

謝謝......我沒有看清楚答案:( –

+0

@meewoK是的,在編寫像這樣的查詢,理解數據,業務規則,以及確切瞭解用戶提出的問題時,通常是最大的挑戰 – Jerry

0

使用派生表,如果你使用MySQL。 基本上,這是有效的,因爲它創建了所有包含<> 1的訂單行的臨時小派生表。然後我們使用NOT條件加入主查詢。

SELECT 
d1.ORDERNumber, 
d1.ORDERLine, 
d1.Package 
FROM data d1,  
(select distinct ORDERLINE, 
PACKAGE from data 
where NOT Package = 1) 
as d2  
WHERE (PartNumber='A1' 
     AND SIZE='S' 
     AND Cost=22.5 
     AND Reviewed='Yes' 
     AND NOT d1.orderline = d2.orderline) 
GROUP BY ORDERNumber, 
     ORDERLine, 
     Package 
HAVING count(ORDERNumber)=1 

http://www.sqlfiddle.com/#!2/b391e/8