数据库管理系统-甲骨文| return 多个表/关系的多个最大值

DBMS - Oracle | return multiple max values for multiple tables / relations

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

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

根据这个截图...

请尝试以下...

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,即只有来自 BookOrderItem 的那些记录的 BookOrder 具有最大值 BOI_Qty ] 将被退回。如果特定 BookOrder 的多个 BookOrderItem 具有该 BookOrder 的最大值 BOI_Qty,则将保留每个这样的记录。

然后将生成的数据集连接到 BookOrder,以便检索 BookOrderBO_CustNum 的值并用于将数据集连接到 Customer ,允许检索与每个 BookOrder 关联的 CustomerName

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

请注意,我已将字段 BOI_ItemNum 包含在所选字段中,因为您要求返回每条具有最大值 BOI_Qty 的记录。没有它,这样的记录似乎会重复。包含 BOI_ItemNum 将使您能够识别返回的每条记录。

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

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

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