2017-05-07 77 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;