数据库管理系统-甲骨文| 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
,以便检索 BookOrder
的 BO_CustNum
的值并用于将数据集连接到 Customer
,允许检索与每个 BookOrder
关联的 Customer
的 Name
。
然后检索并排序我们最终数据集中每条记录的所需字段。
请注意,我已将字段 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;
我需要 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
,以便检索 BookOrder
的 BO_CustNum
的值并用于将数据集连接到 Customer
,允许检索与每个 BookOrder
关联的 Customer
的 Name
。
然后检索并排序我们最终数据集中每条记录的所需字段。
请注意,我已将字段 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;