将值聚合到GROUP BY查询中的表类型中

时间:2010-07-29 22:49:55

标签: oracle plsql group-by types aggregate-functions

假设您有一个表(在Oracle中):

CREATE TABLE CUSTOMER
(
  customer_id NUMBER,
  gender      CHAR(1)
);

假设你有一个表类型:

CREATE TYPE NUMBER_TABLE_TYPE AS TABLE OF NUMBER;

是否可以编写GROUP BY查询,以便对于每个组,该组的主键字段存储在NUMBER_TABLE_TYPE中?例如:

DECLARE
  CURSOR gender_cursor IS
    SELECT
      gender,
      /* The CUSTOMER_IDS column will be of type NUMBER_TABLE_TYPE: */
      SOME_MAGICAL_AGGREGATE_FUNCTION(customer_id) AS customer_ids
    FROM
      CUSTOMER
    GROUP BY
      gender;

  customer_ids NUMBER_TABLE_TYPE;
BEGIN
  FOR gender IN gender_cursor LOOP
    customer_ids := gender.customer_ids;
    FOR i IN customer_ids.FIRST .. customer_ids.LAST LOOP
      dbms_output.put_line(customer_ids(i));
    END LOOP;
  END LOOP;
END;

我知道这应该通过两个游标(一个用于性别组,另一个用于查询每个组的客户)来完成。我很想知道是否可以这样做。 :)

1 个答案:

答案 0 :(得分:3)

实现这一目标的两种方法。 首先,通过分析来获取每行中该性别的所有记录的计数。

DECLARE
  CURSOR gender_cursor IS
    SELECT gender, customer_id, count(*) over (partition by gender) cnt_in_gender,
    FROM   CUSTOMER
    ORDER BY gender;
  v_prev_gender varchar2(1) := '?';
BEGIN
  FOR gender IN gender_cursor LOOP
      IF gender.gender != v_prev gender then
        dbms_output.put_line('You will now see '||gender.cnt_in_gender);
        v_prev_gender := gender.gender);
      END IF;
      dbms_output.put_line(gender.customer_ids);
  END LOOP;
END;

其次,更接近您的要求

DECLARE
  CURSOR gender_cursor IS
    SELECT
      gender,
      /* The CUSTOMER_IDS column will be of type NUMBER_TABLE_TYPE: */
      CAST(COLLECT(customer_id) AS NUMBER_TABLE_TYPE) AS customer_ids
    FROM
      CUSTOMER
    GROUP BY
      gender;

  customer_ids NUMBER_TABLE_TYPE;
BEGIN
  FOR gender IN gender_cursor LOOP
    customer_ids := gender.customer_ids;
    FOR i IN customer_ids.FIRST .. customer_ids.LAST LOOP
      dbms_output.put_line(customer_ids(i));
    END LOOP;
  END LOOP;
END;
相关问题