Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can bend over backwards trying to achieve this in pure SQL or you can create something a bit lengthier but both much easier to understand and more performance efficient - use a <a href="http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/tuning.htm#LNPLS01210" rel="nofollow noreferrer">pipelined function</a></p> <p>In essence the function would accept a ref cursor which would have to be pre-ordered by the ID, and then pipe rows only when a contiguous block of records has ended.</p> <pre><code>CREATE TABLE assignment ( a_id NUMBER, assigned_to VARCHAR2(4000) ); CREATE OR REPLACE package PCK_CONTIGUOUS_GROUPBY as TYPE refcur_t IS REF CURSOR RETURN assignment%ROWTYPE; TYPE outrec_typ IS RECORD ( from_id NUMBER, to_id NUMBER, assigned_to VARCHAR2(4000)); TYPE outrecset IS TABLE OF outrec_typ; FUNCTION f_cont_groupby(p refcur_t) RETURN outrecset PIPELINED; end; / CREATE OR REPLACE package body pck_contiguous_groupby as FUNCTION f_cont_groupby(p refcur_t) RETURN outrecset PIPELINED IS out_rec outrec_typ; in_rec p%ROWTYPE; first_id assignment.a_id%type; last_id assignment.a_id%type; last_assigned_to assignment.assigned_to%type; BEGIN LOOP FETCH p INTO in_rec; EXIT WHEN p%NOTFOUND; IF last_id IS NULL THEN -- First record: don't pipe first_id := in_rec.a_id; ELSIF last_id = in_rec.a_id - 1 AND last_assigned_to = in_rec.assigned_to THEN -- Contiguous block: don't pipe NULL; ELSE -- Block not contiguous: pipe out_rec.from_id := first_id; out_rec.to_id := last_id; out_rec.assigned_to := last_assigned_to; PIPE ROW(out_rec); first_id := in_rec.a_id; END IF; last_id := in_rec.a_id; last_assigned_to := in_rec.assigned_to; END LOOP; CLOSE p; -- Pipe remaining row out_rec.from_id := first_id; out_rec.to_id := last_id; out_rec.assigned_to := last_assigned_to; PIPE ROW(out_rec); RETURN; END; END pck_contiguous_groupby; / </code></pre> <p>and then to try it out, populate the table and run:</p> <pre><code>SELECT * FROM TABLE(pck_contiguous_groupby.f_cont_groupby (CURSOR (SELECT a_id, assigned_to FROM assignment ORDER BY a_id))); </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload