是否有 MULTISET 运算符的替代方案可以避免子查询?
假设您有一个如下表:
CREATE TABLE EMPLOYEE_SALES
(
EMPLOYEE_ID NUMBER,
PRODUCT_ID NUMBER,
SALE_AMOUNT NUMBER
);
假设它的填充方式如下:
+-------------+------------+-------------+ | EMPLOYEE_ID | PRODUCT_ID | SALE_AMOUNT | +-------------+------------+-------------+ | 1 | 100 | 1.05 | | 1 | 200 | 45.67 | | 2 | 100 | 3.25 | | 2 | 200 | 34.29 | +-------------+------------+-------------+
现在,假设我创建一个名为 SALE_TYPE
的自定义类型,它表示 (PRODUCT_ID, SALE_AMOUNT)
元组:
CREATE TYPE SALE_TYPE IS OBJECT
(
PRODUCT_ID NUMBER,
SALE_AMOUNT NUMBER
);
假设我还创建了一个名为 SALES_TYPE
的自定义类型,它表示 SALE_TYPE
的 TABLE
:
CREATE TYPE SALES_TYPE IS TABLE OF SALE_TYPE;
我想查询 EMPLOYEE_SALES
> 按 EMPLOYEE_ID
分组。对于每个 EMPLOYEE_ID
,我希望创建一个包含该员工销售额的 SALES_TYPE
。根据文档,我会做这样的事情:
SELECT
EMPLOYEE_ID,
CAST
(
MULTISET
(
SELECT
PRODUCT_ID,
SALE_AMOUNT
FROM
EMPLOYEE_SALES inner_employee_sales
WHERE
inner_employee_sales.employee_id = employee_sales.employee_id
) AS SALES_TYPE
) AS SALES
FROM
EMPLOYEE_SALES
GROUP BY
EMPLOYEE_ID
我希望这个查询产生这样的结果:
+-------------+------------------------------+ | EMPLOYEE_ID | SALES | +-------------+------------------------------+ | 1 | +------------+-------------+ | | | | PRODUCT_ID | SALE_AMOUNT | | | | +------------+-------------+ | | | | 100 | 1.05 | | | | | 200 | 45.67 | | | | +------------+-------------+ | +-------------+------------------------------+ | 2 | +------------+-------------+ | | | | PRODUCT_ID | SALE_AMOUNT | | | | +------------+-------------+ | | | | 100 | 3.25 | | | | | 200 | 34.29 | | | | +------------+-------------+ | +-------------+------------------------------+
有没有办法在不发出子查询的情况下获得相同的结果(我是真实查询工作比这个人为的例子复杂得多)?例如,有没有这样的事情:
SELECT
EMPLOYEE_ID,
CAST
(
COLLECT_ALL_RECORDS_WITHIN_THE_CURRENT_GROUP(
PRODUCT_ID,
SALE_AMOUNT
)
AS SALES_TYPE
) AS SALES
FROM
EMPLOYEE_SALES
GROUP BY
EMPLOYEE_ID
Suppose you have a table as follows:
CREATE TABLE EMPLOYEE_SALES
(
EMPLOYEE_ID NUMBER,
PRODUCT_ID NUMBER,
SALE_AMOUNT NUMBER
);
And suppose it is populated as follows:
+-------------+------------+-------------+ | EMPLOYEE_ID | PRODUCT_ID | SALE_AMOUNT | +-------------+------------+-------------+ | 1 | 100 | 1.05 | | 1 | 200 | 45.67 | | 2 | 100 | 3.25 | | 2 | 200 | 34.29 | +-------------+------------+-------------+
Now, suppose I create a custom type named SALE_TYPE
which represents a (PRODUCT_ID, SALE_AMOUNT)
tuple:
CREATE TYPE SALE_TYPE IS OBJECT
(
PRODUCT_ID NUMBER,
SALE_AMOUNT NUMBER
);
And suppose I also create a custom type named SALES_TYPE
which represents a TABLE
of SALE_TYPE
:
CREATE TYPE SALES_TYPE IS TABLE OF SALE_TYPE;
I want to query the EMPLOYEE_SALES
table group by EMPLOYEE_ID
. For each EMPLOYEE_ID
, I wish to create a SALES_TYPE
containing that employee's sales. According to the documentation, I would do something like this:
SELECT
EMPLOYEE_ID,
CAST
(
MULTISET
(
SELECT
PRODUCT_ID,
SALE_AMOUNT
FROM
EMPLOYEE_SALES inner_employee_sales
WHERE
inner_employee_sales.employee_id = employee_sales.employee_id
) AS SALES_TYPE
) AS SALES
FROM
EMPLOYEE_SALES
GROUP BY
EMPLOYEE_ID
I expect this query to yield something like this:
+-------------+------------------------------+ | EMPLOYEE_ID | SALES | +-------------+------------------------------+ | 1 | +------------+-------------+ | | | | PRODUCT_ID | SALE_AMOUNT | | | | +------------+-------------+ | | | | 100 | 1.05 | | | | | 200 | 45.67 | | | | +------------+-------------+ | +-------------+------------------------------+ | 2 | +------------+-------------+ | | | | PRODUCT_ID | SALE_AMOUNT | | | | +------------+-------------+ | | | | 100 | 3.25 | | | | | 200 | 34.29 | | | | +------------+-------------+ | +-------------+------------------------------+
Is there a way to achieve the same results without issuing a sub-query (the real query I am working on is much more complicated than this contrived example)? For example, is there something like this:
SELECT
EMPLOYEE_ID,
CAST
(
COLLECT_ALL_RECORDS_WITHIN_THE_CURRENT_GROUP(
PRODUCT_ID,
SALE_AMOUNT
)
AS SALES_TYPE
) AS SALES
FROM
EMPLOYEE_SALES
GROUP BY
EMPLOYEE_ID
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 Oracle 10g 中,您可以使用 COLLECT 运算符,如下所示:
In Oracle 10g, you can use the COLLECT operator as follows:
您应该能够编写自定义聚合函数 11.2 之前创建的用于连接字符串的聚合函数和 LISTAGG 函数。
例如,我可以创建一个 EMP_OBJ 对象和这些对象的集合 (EMP_TBL),并编写一个自定义聚合函数,该函数从简单的 SQL 语句生成 EMP_TBL 集合
创建基本类型
创建我们将用于进行聚合的类型
声明聚合函数
现在,使用我们自定义聚合函数的简单 GROUP BY 将生成 EMP_TBL 集合
You should be able to write a custom aggregate function along the lines of the aggregate functions that were created to concatenate strings before 11.2 and the LISTAGG function.
For example, I can create an EMP_OBJ object and a collection of those objects (EMP_TBL) and write a custom aggregate function that generates an EMP_TBL collection from a simple SQL statement
Create the basic types
Create the type that we'll use to do the aggregation
Declare the aggregate function
And now a simple GROUP BY using our custom aggregate function will generate an EMP_TBL collection