6.2Bloom · ANot started

CDS patterns that compress code

Reading depth

What you'll learn

Aggregation, associations and group by turn loops-and-COLLECT into a few declarative lines — but the group by must list every non-aggregated field.

  • Aggregation (count/sum/max/min/avg), associations, and group by compress the most code.
  • Associations are declared joins, navigated by name and materialized only when used.
  • Every non-aggregated select field must appear in the group by.

A surprising amount of classic ABAP — nested loops, COLLECT statements, manual subtotalling — collapses into a few lines of CDS. The three patterns that compress the most code are aggregation (count, sum, max, min, avg), associations (declared joins you navigate by name), and group by. Written as a `define view entity ... as select from ...`, the view is pushed to HANA and consumable everywhere.

Aggregation replaces hand-rolled totalling: `count(*)`, `sum(h.total)`, `max(h.orderdate)` are computed on the database in a single scan. Associations replace repeated explicit joins: you declare `association [0..*] to zorder_item as _items on ...` once and expose or navigate it by name, and the join is materialized only when the association is actually used. Together they turn a screen of procedural code into a declarative contract.

The rule that commonly trips up newcomers: when a view aggregates, the `group by` must list *every* non-aggregated field in the select list. Miss one and the view often activates but errors at runtime — the activator catches many cases, but not when an expression appears in the select. Treat it as a discipline: every plain field in the projection appears verbatim in the group by.

Key points

  • Aggregation (count/sum/max/min/avg), associations, and group by compress the most code.
  • Associations are declared joins, navigated by name and materialized only when used.
  • Every non-aggregated select field must appear in the group by.
  • A missing group-by field may activate but error at runtime — expressions slip past the activator.
  • Use `define view entity` (CDS view entity), not the legacy DDIC-based `define view`.

Examples

BeforeHand-rolled totalling in ABAP

Classic: select all rows, then loop and collect per customer — rows travel to the app server just to be counted.

ABAPselect customerid, total, orderdate
  from zorder_hdr
  where status = 'OPEN'
  into table @data(lt_hdr).
loop at lt_hdr assigning field-symbol(<h>).
  ls_sum-customerid = <h>-customerid.
  ls_sum-ordercount = 1.
  ls_sum-totalopen  = <h>-total.
  collect ls_sum into lt_sum.
endloop.
AfterThe same logic as a CDS view entity

Aggregation, an association and a group by covering every non-aggregated field; pushed to HANA, consumable from Open SQL, RAP, analytics and OData.

ABAP@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Open Orders By Customer'
define view entity ZI_OpenOrdersByCustomer
  as select from zorder_hdr as h
  association [0..*] to zorder_item as _items
    on _items.OrderId = h.OrderId
{
  key h.CustomerId,
      count(*)         as OrderCount,
      sum(h.Total)     as TotalOpenAmount,
      max(h.OrderDate) as LastOrderDate,
      _items
}
where h.Status = 'OPEN'
group by h.CustomerId

Source notes: clean-core-curriculum §6.2

Ask Claude

Build a prompt from this lesson + your question and open a fresh Claude chat with it pre-filled — handy for adapting a before/after pattern to your own object.