2017-05-07 42 views
-1

我需要返回已訂購最大數量項目的客戶列表。我已添加以下內容並獲得一些結果,但需要過濾查詢以顯示多個最大值。DBMS - Oracle |返回多個表/關係的多個最大值

DDL

CREATE TABLE Customer 
(Cust_Num NUMBER(4) PRIMARY KEY, 
Cust_LName VARCHAR2(10), 
Cust_FName VARCHAR2(10), 
Cust_Address VARCHAR2(20), 
Cust_City VARCHAR2(12), 
Cust_State VARCHAR2(2), 
Cust_Zip VARCHAR2(5), 
Cust_Referred NUMBER(4)); 

Create Table BookOrder 
(BO_OrderNum NUMBER(4) PRIMARY KEY, 
BO_CustNum NUMBER(4) REFERENCES Customer(Cust_Num), 
BO_OrderDate DATE, 
BO_ShipDate DATE, 
BO_ShipStreet VARCHAR2(18), 
BO_ShipCity VARCHAR2(15), 
BO_ShipState VARCHAR2(2), 
BO_ShipZip VARCHAR2(5)); 

CREATE TABLE BookOrderItem 
(BOI_OrderNum NUMBER(4) NOT NULL REFERENCES BookOrder(BO_OrderNum), 
BOI_ItemNum NUMBER(2) NOT NULL, 
BOI_ISBN VARCHAR2(10) REFERENCES Book(Book_ISBN), 
BOI_Qty NUMBER(3), 
CONSTRAINT bookorderitem_pk PRIMARY KEY (BOI_OrderNum, BOI_ItemNum)); 

我寫了下面的DML:

SELECT C.CUST_LNAME, C.CUST_FNAME, BO.BO_CUSTNUM, BOI.BOI_ORDERNUM, 
COUNT(BOI.BOI_ITEMNUM) AS Total_Items_Per_Order 
FROM BookOrderItem BOI JOIN BookOrder BO ON BOI.BOI_OrderNum = BO.BO_OrderNum 
JOIN Customer C ON C.Cust_Num = BO.BO_CustNum 
GROUP BY C.Cust_LName, C.CUST_FName, BO.BO_CustNum, BOI.BOI_OrderNum 
ORDER BY Total_Item_Per_Order DESC; 

這給了我下面的結果...

+------------+------------+------------+--------------+-----------------------+ 
| CUST_LNAME | CUST_FNAME | BO_CustNum | BOI_OrderNum | TOTAL_ITEMS_PER_ORDER | 
+------------+------------+------------+--------------+-----------------------+ 
| NELSON  | BECCA  | 1017  | 1012   | 4      | 
| GIANA  | TAMMY  | 1007  | 1007   | 4      | 
| MORALES | BONITA  | 1001  | 1003   | 3      | 
| MORALES | BONITA  | 1001  | 1018   | 2      | 
| LUCAS  | JAKE  | 1010  | 1001   | 2      | 
| GIRARD  | CINDY  | 1005  | 1009   | 2      | 
| LEE  | JASMINE | 1014  | 1013   | 1      | 
| MONTIASA | GREG  | 1018  | 1005   | 1      | 
| MONTIASA | GREG  | 1018  | 1019   | 1      | 
| PIERSON | THOMAS  | 1004  | 1008   | 1      | 
| JONES  | KENNETH | 1008  | 1020   | 1      | 
| MCGOVERN | REESE  | 1011  | 1002   | 1      | 
| LUCAS  | JAKE  | 1010  | 1011   | 1      | 
| FALAH  | KENNETH | 1020  | 1015   | 1      | 
| SMITH  | JENNIFER | 1019  | 1010   | 1      | 
| GIRARD  | CINDY  | 1005  | 1000   | 1      | 
| SMITH  | LEILA  | 1003  | 1006   | 1      | 
| GIANA  | TAMMY  | 1007  | 1014   | 1      | 
| FALAH  | KENNETH | 1020  | 1004   | 1      | 
| SMITH  | LEILA  | 1003  | 1016   | 1      | 
| SCHELL  | STEVE  | 1015  | 1017   | 1      | 
+------------+------------+------------+--------------+-----------------------+ 

按照這個截圖...

+1

要提高你的問題的質量,請重現問題的範圍,而不是作爲鏈接的圖像輸出作爲格式化文本。這是因爲不得不導航到鏈接的圖像有點不方便,因爲鏈接可能隨時間而中斷。如果你必須在你的問題中包含圖像,使用'[] [1]'將使你能夠在你的問題中顯示它,而不是作爲鏈接。我在這裏使用了'[]',因爲你不需要輸入圖像描述,但仍然需要括號。如果您使用了多個圖像,請記住將'1'更改爲圖像編號。 – toonice

+0

提供一些示例數據和預期輸出。 – Utsav

+0

理想情況下,它應該返回具有每個訂單號最大數量的商品的行。如果兩個訂單號具有相同數量的項目,則應返回兩行。 –

回答

0

請嘗試以下...

SELECT Cust_LName, 
     Cust_FName, 
     Cust_Num AS Cust_Num, 
     BO_OrderNum AS Order_Num, 
     BOI_ItemNum AS Item_Num, 
     Max_Qty_Per_Order AS Max_Qty_Per_Order 
FROM (SELECT BOI_OrderNum AS Order_Num, 
       MAX(BOI_Qty) AS Max_Qty_Per_Order 
     FROM BookOrderItem 
     GROUP BY BOI_OrderNum 
    ) Max_Qty_Per_Order_Finder 
JOIN BookOrderItem ON BookOrderItem.BOI_OrderNum = Max_Qty_Per_Order_Finder.Order_Num 
        AND BookOrderItem.BOI_Qty = Max_Qty_Per_Order_Finder.Max_Qty_Per_Order 
JOIN BookOrder ON Max_Qty_Per_Order_Finder.Order_Num = BookOrder.BO_OrderNum 
JOIN Customer Customer ON Customer.Cust_Num = BookOrder.BO_CustNum 
ORDER BY Max_Qty_Per_Order DESC, 
     BO_OrderNum, 
     BOI_Item_Num; 

這種說法開始通過創建訂單號碼和BOI_Qty相關的每一個最大值的列表。

此子查詢的結果將在只有來自BookOrderItem這些記錄具有的BOI_Qty他們BookOrder將返回的最大值這樣的方式連接到BookOrderItem。如果特定BookOrder的一個以上BookOrderItem對於該BookOrder具有最大值BOI_Qty,則每個這樣的記錄將被保留。

將所得數據集然後被接合到BookOrder使得BO_CustNumBookOrder值可以被檢索和被用於連接數據集Customer,允許與每個BookOrder相關聯的CustomerName被檢索。

然後檢索並排序我們最終數據集中每個記錄的所需字段。

請注意,根據您詢問要返回的最大值爲BOI_Qty的每條記錄,我已在選定字段中包含字段BOI_ItemNum。沒有它,這些記錄似乎會重複。包括BOI_ItemNum將允許您識別返回的每條記錄。

如果您有任何問題或意見,請隨時發佈相應評論。

1

要僅保留第一行,您將在Oracle 12c中使用FETCH FIRST n ROW(s) ONLY。要考慮的聯繫,你會通過WITH TIES更換ONLY

... 
ORDER BY Total_Item_Per_Order DESC 
FETCH FIRST 1 ROW WITH TIES;