DBMS - Oracle |为多个表/关系返回多个最大值

时间:2017-05-07 04:00:00

标签: sql oracle oracle12c

我需要返回订购了最大数量项目的客户列表。我添加了以下内容并获得了一些结果,但需要过滤查询以显示多个最大值。

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                     |
+------------+------------+------------+--------------+-----------------------+

根据此截图...

2 个答案:

答案 0 :(得分:1)

要仅保留您在Oracle 12c中使用FETCH FIRST n ROW(s) ONLY的第一行。要考虑关系,请将ONLY替换为WITH TIES

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

答案 1 :(得分: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,只有BookOrderItemBOI_Qty的{​​{1}}最大值的BookOrder被退回如果特定BookOrderItem的多个BookOrder的{​​{1}}的最大值为BOI_Qty,则会保留每条此类记录。

然后,结果数据集将加入BookOrder,以便检索BookOrder的{​​{1}}值,并将其用于将数据集加入BO_CustNum,从而允许与要检索的每个BookOrder相关联的Customer的{​​{1}}。

然后检索并排序最终数据集中每条记录的所需字段。

请注意,我已在所选字段中包含字段Name,因为您要求返回的最大值为Customer的每条记录。没有它,这样的记录似乎会重复。包括BookOrder将允许您识别返回的每条记录。

如果您有任何问题或意见,请随时发表评论。