Skip to main content
SAP HANAHANA 2.0+

HANA CDS Views Essential Cheat Sheet

Comprehensive reference guide for HANA Core Data Services (CDS) including view definitions, associations, annotations, calculations, and professional development best practices.

Quick Reference

Most commonly used CDS features at a glance

FeatureSQL ViewCDS View
Basic selectCREATE VIEW v AS SELECT * FROM tabledefine view v as select from table
AliasSELECT a.col FROM tab aselect from tab as a
JoinINNER/LEFT/RIGHT JOINassociation [1:1] / [1:n]
FilteringWHERE clausewhere condition
GroupingGROUP BYgroup by fields
SortingORDER BYorder by field asc/desc
AnnotationN/A@annotation: value
ParameterVariable in trigger@Parameter.parameter
CalculationCASE expressioncast(...as type), calculation
Access controlViews only@AccessControl.authorizationCheck
About HANA CDS Views
CDS (Core Data Services) provides a powerful abstraction layer over HANA database with semantic metadata, business logic, and reusability. CDS views are the modern way to define data models in SAP HANA.

Basic CDS Syntax

Fundamental CDS view definition

Simple CDS View
Basic view definition with select statement
define view ZMY_VIEW as
  select from MARA {
    key matnr,
        mtart,
        maktx,
        meins
  };

// With alias
define view ZMY_VIEW as
  select from MARA as mara {
    key mara.matnr,
        mara.mtart as material_type,
        mara.meins as unit
  };

// From another CDS view
define view ZMY_VIEW2 as
  select from ZMY_VIEW {
    key matnr,
        material_type
  };

// Multiple tables
define view ZMY_VIEW3 as
  select from MARA as m {
    key m.matnr,
        m.mtart,
        m.meins
  }
  where m.mtart = 'FERT';

// Distinct values
define view ZMY_VIEW4 as
  select distinct from MARA {
    key mtart,
        meins
  };
Best Practice
Always use alias (as clause) to avoid ambiguity in complex views. Use descriptive names with prefixes like Z for custom objects.

Filtering & Sorting

WHERE, GROUP BY, and ORDER BY

Where & Group By
Filter and aggregate data
// Simple WHERE clause
define view ZMY_VIEW as
  select from MARA {
    key matnr,
        mtart,
        meins
  }
  where mtart = 'FERT';

// Multiple conditions
define view ZMY_VIEW as
  select from MARA {
    key matnr,
        mtart
  }
  where mtart = 'FERT' and meins = 'ST';

// IN condition
define view ZMY_VIEW as
  select from MARA {
    key matnr
  }
  where mtart in ('FERT', 'HALB');

// LIKE pattern
define view ZMY_VIEW as
  select from MARA {
    key matnr,
        maktx
  }
  where maktx like 'Material%';

// GROUP BY aggregation
define view ZMY_STATS as
  select from MARA {
        mtart,
        count(*) as cnt : int,
        count(distinct meins) as distinct_units : int
  }
  group by mtart;

// ORDER BY
define view ZMY_VIEW as
  select from MARA {
    key matnr,
        mtart,
        meins
  }
  order by mtart asc, meins desc;

// UNION
define view ZMY_UNION as
  select from MARA { matnr as id, mtart as type }
  union
  select from MAKT { pernr as id, mtart as type };

Associations

Relationships between CDS views

One-to-One Associations
1:1 relationships
// Define association
define view ZMATERIAL as
  select from MARA {
    key matnr,
        mtart,
        meins,
        
        // One-to-one association
        association [1:1] to MAKT
          on $projection.matnr = MAKT.matnr
          and MAKT.spras = 'E'
        as description
  };

// Use association in another view
define view ZMATERIAL_EXTENDED as
  select from ZMATERIAL {
    key matnr,
        mtart,
        meins,
        
        // Expose association
        description
  };

// Access association in query
select from ZMATERIAL {
  matnr,
  mtart,
  description.maktx as description
};

// Foreign key style
define view ZUSER_WITH_ORG as
  select from USR01 {
    key bname,
        datlo,
        
        association [1:1] to T001
          on $projection.mandt = T001.mandt
        as organization
  };
One-to-Many Associations
1:n relationships
// One-to-many association
define view ZCUSTOMER_ORDERS as
  select from KNA1 {
    key kunnr,
        name1,
        land1,
        
        // One-to-many association
        association [1:n] to VBAK
          on $projection.kunnr = VBAK.kunnr
        as orders
  };

// Using 1:n in query
select from ZCUSTOMER_ORDERS as cust
  left outer join VBAK as ord
  on cust.kunnr = ord.kunnr
{
  cust.kunnr,
  cust.name1,
  ord.vbeln as order_id
};

// Nested associations
define view ZORDER_DETAILS as
  select from VBAK {
    key vbeln,
        kunnr,
        
        association [1:n] to VBAP
          on $projection.vbeln = VBAP.vbeln
        as items,
        
        association [1:1] to ZCUSTOMER_ORDERS
          on $projection.kunnr = ZCUSTOMER_ORDERS.kunnr
        as customer
  };

// Composition (strong ownership)
define view ZORDER_COMPOSITION as
  select from VBAK {
    key vbeln,
        kunnr,
        
        composition [1:n] of VBAP
          on $projection.vbeln = VBAP.vbeln
        as items
  };
Association Best Practice
Use associations for semantic relationships. They enable proper navigation in SAP UI5 and improve query performance through lazy loading.

Calculations & Expressions

Calculated fields and expressions

Calculated Fields
Add computed columns
// String concatenation
define view ZMY_VIEW as
  select from KNA1 {
    key kunnr,
        concat(name1, ' ', name2) as full_name : string,
        upper(city) as city_upper : string
  };

// Arithmetic
define view ZMATERIAL_PRICE as
  select from MARA {
    key matnr,
        meins,
        1000 as standard_price : decimal(10,2),
        standard_price * 1.19 as price_with_tax : 
          decimal(10,2)
  };

// CAST and type conversion
define view ZMY_VIEW as
  select from VBAK {
    key vbeln,
        cast(erdat as date) as order_date : date,
        cast(netwr as decimal(13,2)) as amount : 
          decimal(13,2)
  };

// CASE expression
define view ZORDER_STATUS as
  select from VBAK {
    key vbeln,
        case vbtyp
          when 'C' then 'Order'
          when 'K' then 'Quotation'
          else 'Other'
        end as document_type : string
  };

// Arithmetic with CASE
define view ZORDER_DISCOUNT as
  select from VBAP {
    key vbeln,
        key posnr,
        netwr,
        case 
          when kwmeng > 100 then netwr * 0.10
          when kwmeng > 50 then netwr * 0.05
          else 0
        end as discount_amount : decimal(13,2)
  };

Aggregation Functions

COUNT, SUM, AVG, MAX, MIN

Aggregate Functions
Summarize data
// COUNT aggregation
define view ZSALES_COUNT as
  select from VBAK {
        kunnr,
        count(*) as order_count : int,
        count(distinct vbeln) as distinct_orders : int,
        count(vbeln) as total_lines : int
  }
  group by kunnr;

// SUM aggregation
define view ZSALES_TOTAL as
  select from VBAK {
        kunnr,
        sum(netwr) as total_sales : decimal(15,2),
        sum(case when vbtyp = 'C' 
            then netwr else 0 end) 
          as order_total : decimal(15,2)
  }
  group by kunnr;

// AVG, MAX, MIN
define view ZORDER_STATS as
  select from VBAK {
        kunnr,
        avg(netwr) as avg_order : decimal(13,2),
        max(netwr) as max_order : decimal(13,2),
        min(netwr) as min_order : decimal(13,2)
  }
  group by kunnr;

// Multiple aggregations
define view ZCOMPLEX_STATS as
  select from VBAP {
        matnr,
        sum(kwmeng) as total_qty : decimal(13,3),
        avg(netpr) as avg_price : decimal(13,2),
        count(*) as line_count : int,
        max(kwmeng) as max_qty : decimal(13,3)
  }
  group by matnr;

// HAVING clause (filter after grouping)
define view ZACTIVE_MATERIALS as
  select from VBAP {
        matnr,
        count(*) as sales_count : int
  }
  group by matnr
  having count(*) > 10;

Annotations

Metadata and semantic information

Common Annotations
Add meaning and configuration to views
// UI annotations
define view ZMY_VIEW
  @UI.headerInfo: { typeName: 'Material', typeNamePlural: 'Materials' }
as
  select from MARA {
    key matnr,
        mtart,
        meins
  };

// Metadata and labels
@EndUserText.label: 'Material Master View'
@EndUserText.description: 'Complete material information'
define view ZMY_MATERIAL as
  select from MARA {
    key matnr : mara.matnr
      @EndUserText.label: 'Material Number',
        mtart : mara.mtart
      @EndUserText.label: 'Material Type',
        meins : mara.meins
      @EndUserText.label: 'Unit of Measure'
  };

// Semantic annotations
@Semantics.systemDate.lastChangedAt: true
define view ZCUSTOMER_WITH_META as
  select from KNA1 {
    key kunnr,
        name1,
        laeda as changed_date : date
  };

// Text association
define view ZCUSTOMER_VIEW as
  select from KNA1 {
    key kunnr,
        name1 : KNA1.name1
          @Semantics.text: true,
        land1
  };

// Currency/Quantity annotations
define view ZORDER_AMOUNTS as
  select from VBAK {
    key vbeln,
        waerk : vbak.waerk
          @Semantics.currencyCode: true,
        netwr : vbak.netwr
          @Semantics.amount.currencyCode: 'waerk'
  };

// Access control annotation
@AccessControl.authorizationCheck: #CHECK
define view ZSENSITIVE_DATA as
  select from VBAK {
    key vbeln,
        kunnr,
        netwr
  };

// Searchable and sortable
define view ZPRODUCT_VIEW as
  select from MARA {
    key matnr,
        mtart : mara.mtart
          @Search.defaultSearchElement: true
          @EndUserText.label: 'Type',
        maktx
          @Search.defaultSearchElement: true
  };
Annotation Benefits
Annotations provide semantic meaning that powers SAP UI5 applications, OData services, and analytics tools. Always document your views with annotations.

Parameters & Actions

Input parameters and operations

View Parameters
Accept input parameters
// Simple parameter
define view ZMAT_BY_TYPE
  (p_mtart: abap.char(4))
as
  select from MARA {
    key matnr,
        mtart,
        meins
  }
  where mtart = :p_mtart;

// Multiple parameters
define view ZMAT_FILTERED
  (p_mtart: abap.char(4),
   p_meins: abap.char(3),
   p_active: abap.char(1) = 'X')
as
  select from MARA {
    key matnr,
        mtart,
        meins
  }
  where mtart = :p_mtart
    and meins = :p_meins;

// Parameter with default
define view ZORDERS_TODAY
  (p_date: abap.dats = 
    $session.system_date)
as
  select from VBAK {
    key vbeln,
        erdat,
        netwr
  }
  where erdat = :p_date;

// Using $session and $user
define view ZUSER_ORDERS
  (p_user: abap.char(12) = $user.id)
as
  select from VBAK {
    key vbeln,
        ernam,
        netwr
  }
  where ernam = :p_user;

// Parameter in calculation
define view ZPRICED_MATERIALS
  (p_currency: abap.cuky = 'USD')
as
  select from MARA {
    key matnr,
        mtart,
        cast(1000 as decimal(10,2)) 
          as price : decimal(10,2),
        :p_currency as currency : abap.cuky
  };
Actions & Custom Logic
Define actions on views
// Action definition (binding aware)
define view ZORDER_ACTIONS as
  select from VBAK {
    key vbeln,
        kunnr,
        vbtyp,
        
        // Action for confirmation
        @UI.hidden: true
        case vbtyp 
          when 'C' then 'CONFIRM'
          else ''
        end as confirm_action : string
  };

// Status-based actions
define view ZDOCUMENT_WORKFLOW as
  select from VBAK {
    key vbeln,
        status : vbak.vbtyp,
        
        case status
          when 'DRAFT' then 'SUBMIT'
          when 'SUBMITTED' then 'APPROVE'
          when 'APPROVED' then 'POST'
          else ''
        end as next_action : string
  };

// Conditional field visibility
@UI.hidden: #(processing)
define view ZCONDITIONAL_VIEW as
  select from VBAK {
    key vbeln,
        kunnr,
        
        case 
          when vbtyp = 'C' then 1
          else 0
        end as processing : int
  };

// Virtual element (for custom actions)
define view ZORDERS_WITH_ACTIONS as
  select from VBAK {
    key vbeln,
        kunnr,
        vbtyp,
        
        // Indicator field
        case 
          when netwr > 10000 then 'HIGH'
          when netwr > 5000 then 'MEDIUM'
          else 'LOW'
        end as priority : string
  };

Advanced CDS Features

Complex queries and patterns

Advanced Techniques
Complex CDS patterns
// Nested select with join
define view ZCOMPLEX_VIEW as
  select from MARA as m
    left outer join MAKT as t
    on m.matnr = t.matnr
    and t.spras = 'E'
  left outer join MARC as c
    on m.matnr = c.matnr
    and c.werks = '1000'
  {
    key m.matnr,
        m.mtart,
        t.maktx as description,
        c.labst as stock
  };

// Subquery in SELECT
define view ZMAT_WITH_ORDERS as
  select from MARA as m {
    key m.matnr,
        m.mtart,
        
        (select count(*) from VBAP as v 
         where v.matnr = m.matnr) 
         as order_count : int
  };

// UNION with different structures
define view ZCOMBINED_DOCS as
  select from VBAK {
    vbeln as doc_id,
    'ORDER' as doc_type,
    netwr as amount
  }
  union
  select from VBRK {
    vbeln as doc_id,
    'INVOICE' as doc_type,
    netwr as amount
  };

// Window functions (SAP HANA 2.0+)
define view ZRANK_MATERIALS as
  select from VBAP {
    key vbeln,
        key posnr,
        matnr,
        kwmeng,
        
        rank() over (
          partition by vbeln 
          order by kwmeng desc
        ) as rank : int
  };

// ROW_NUMBER
define view ZROW_NUMBERED as
  select from MARA {
    key matnr,
        mtart,
        
        row_number() over (
          order by matnr
        ) as row_num : int
  };

// Cross join (cartesian product)
define view ZCROSS_MATERIALS as
  select from MARA as m
    cross join MARC as c
    on m.matnr = c.matnr
  {
    key m.matnr,
        c.werks as plant
  }
  where m.mtart = 'FERT';
Performance Consideration
Use window functions carefully - they can be expensive. Subqueries in SELECT should filter early. Always check execution plans with HANA Studio or Cloud Studio.

Best Practices

Professional CDS development

PracticeDescriptionExample
Use aliasesAlways alias tables for clarityselect from MARA as m { m.matnr }
Key fields firstDefine keys at the beginningkey matnr, key posnr,
Explicit castingCast to target typescast(field as type)
Name conventionsUse prefixes and suffixesZ_MATERIAL_V for views
AssociationsUse for relationshipsassociation [1:1] to MAKT
AnnotationsDocument all fields@EndUserText.label
Reduce data earlyFilter at lowest levelwhere clause in base view
Reuse viewsBuild on existing viewsselect from existing_view
Avoid SELECT *Explicitly list fieldsselect from MARA { field1, field2 }
Partition keyDesign for parallel processingpartition by key_field
Index awarenessConsider DB indexesjoin on indexed columns
Document purposeClear descriptions@EndUserText.description

Naming Conventions:

// View naming
Z_CUSTOMER_V           // Base view suffix _V
Z_CUSTOMER_ORDERS_V    // Descriptive names
Z_CUSTOMER_STAT_V      // Purpose clear

// Field naming
define view ZCUSTOMER_V as
  select from KNA1 {
    key kunnr,           // Clear name
        name1 as customer_name : string,
        land1 as country : string,
        erdat as created_date : date,
        aedat as changed_date : date
  };

// Hierarchy
// Base views (transactional data)
Z_CUSTOMER_V
Z_ORDER_V

// Extended views (with enrichment)
Z_CUSTOMER_EXTENDED_V
Z_ORDER_WITH_DETAILS_V

// Calculated views (aggregations)
Z_CUSTOMER_STATS_V
Z_SALES_SUMMARY_V

Performance Tips:

// ✓ Good: Filter early
define view ZACTIVE_MAT as
  select from MARA {
    key matnr
  }
  where mtart = 'FERT'    // Filter here
    and meins = 'ST';

// ✗ Avoid: Filtering in application
// Application does: WHERE mtart = 'FERT'

// ✓ Good: Use associations
select from ZCUSTOMER_V {
  kunnr,
  customer.name1    // Lazy loaded
};

// ✗ Avoid: Multiple joins
select from KNA1 join VBAK ...

// ✓ Good: Projections
select from ZCUSTOMER_V {
  kunnr, name1      // Only needed fields
};

// ✗ Bad: Expose all
select from ZCUSTOMER_V { * };

Common Patterns

Reusable CDS patterns

Master Data View
Typical master data pattern
@EndUserText.label: 'Material Master'
@EndUserText.description: 'Complete material information'
define view ZMATERIAL_V as
  select from MARA as m
    left outer join MAKT as t
      on m.matnr = t.matnr
      and t.spras = 'E'
    left outer join MARC as c
      on m.matnr = c.matnr
      and c.werks = '1000'
  {
    key m.matnr,
        m.mtart : mara.mtart
          @EndUserText.label: 'Type',
        t.maktx : makt.maktx
          @EndUserText.label: 'Description',
        c.labst : marc.labst
          @EndUserText.label: 'Stock'
  }
  where m.mtart in ('FERT', 'HALB');
Aggregation View
Summary/statistics pattern
define view ZSALES_SUMMARY_V as
  select from VBAP {
        kunnr,
        matnr,
        sum(kwmeng) as total_qty : decimal(13,3),
        sum(netwr) as total_amount : decimal(15,2),
        count(*) as line_count : int,
        avg(netpr) as avg_price : decimal(13,2)
  }
  group by kunnr, matnr
  having count(*) > 0
  order by total_amount desc;
Hierarchy View
Master detail relationship
define view ZORDER_HIERARCHY_V as
  select from VBAK {
    key vbeln,
        kunnr,
        erdat,
        
        association [1:n] to VBAP
          on $projection.vbeln = VBAP.vbeln
        as items,
        
        association [1:1] to ZCUSTOMER_V
          on $projection.kunnr = ZCUSTOMER_V.kunnr
        as customer
  }
  where vbtyp = 'C';
Status View
Workflow/status pattern
define view ZDOCUMENT_STATUS_V as
  select from VBAK {
    key vbeln,
        case vbtyp
          when 'C' then 'ORDER'
          when 'K' then 'QUOTATION'
          else 'OTHER'
        end as doc_type : string,
        
        case
          when vbtyp = 'C' then 'ACTIVE'
          else 'INACTIVE'
        end as status : string
  };

Data Types & Conversions

ABAP type mappings in CDS

Common ABAP Types in CDS
Type definitions and conversions
// Text types
define view ZTYPE_DEMO as
  select from MARA {
    key matnr : abap.char(18),        // Character
        maktx : abap.string,           // String
        meins : abap.unit              // Unit
  };

// Numeric types
define view ZCALC_TYPES as
  select from VBAP {
    key vbeln : abap.char(10),
        kwmeng : abap.quan(13,3),      // Quantity
        netpr : abap.curr(13,2),       // Currency
        percentage : abap.dec(5,2),    // Decimal
        counter : abap.int4            // Integer
  };

// Date and Time
define view ZDATE_DEMO as
  select from VBAK {
    key vbeln,
        erdat : abap.dats,             // Date
        erzet : abap.tims,             // Time
        created : abap.utclong          // Timestamp
  };

// Boolean and flags
define view ZFLAG_DEMO as
  select from MARA {
    key matnr,
        case 
          when mtart = 'FERT' then 'X'
          else ''
        end as is_finished : abap.char(1)
  };

// Currency and quantity codes
@Semantics.currencyCode: true
define view ZCURR_DEMO as
  select from VBAK {
    key vbeln,
        waerk : abap.cuky,             // Currency code
        netwr : abap.curr(13,2)
  };

// Casting examples
define view ZCAST_DEMO as
  select from MARA {
    key matnr,
        cast(matnr as abap.string) as str_matnr : 
          abap.string,
        cast(1000.50 as abap.dec(13,2)) as price : 
          abap.dec(13,2),
        cast('20240118' as abap.dats) as date_field : 
          abap.dats
  };

Performance & Optimization

Optimize CDS view execution

IssueProblemSolution
Large result setMemory consumption, slow executionAdd WHERE clause, use LIMIT
Multiple joinsComplex execution planUse associations instead
SubqueriesMultiple passes through dataJoin parent data or filter early
SELECT *Unnecessary columnsExplicitly list needed fields
No indexesFull table scanDesign keys for DB indexes
Wrong join typeExtra rows processedUse LEFT/INNER correctly
Late filteringProcess unnecessary dataFilter at lowest level
Missing associationsRedundant joinsUse associations for relationships
Window functionsExpensive computationsOnly on pre-filtered data
Type mismatchesImplicit conversionsUse correct types upfront
Debugging Performance
Use SAP HANA Studio → SQL Plan to analyze execution. Check for full table scans and missing indexes. Monitor view compilation in log files.

Common Pitfalls & Solutions

Avoid these CDS mistakes

PitfallProblemSolution
Circular associationsCan't compile viewsReorganize view hierarchy
Missing key fieldsCan't modify data in UIAlways define primary keys
SELECT *Breaks if source changesExplicit field list
Type conflictsImplicit conversion errorsUse explicit CAST
Wrong associationsReturns wrong dataVerify association conditions
No CASE ELSENULL values returnedAdd ELSE clause in CASE
Parameter type mismatchRuntime errorsMatch types exactly
Ambiguous aliasesDuplicate column namesAlways use alias.field
Missing WHERE keysWrong filter behaviorInclude all key conditions
Performance regressionQuery got slowCheck execution plan, reindex

Migration from SQL Views

Converting traditional SQL views to CDS

Traditional SQL → CDS:

-- Old SQL View
CREATE VIEW V_MATERIAL AS
  SELECT m.matnr, m.mtart, t.maktx
  FROM MARA m
  LEFT JOIN MAKT t
    ON m.matnr = t.matnr
    AND t.spras = 'E'
  WHERE m.mtart = 'FERT';

↓

// New CDS View
define view Z_MATERIAL_V as
  select from MARA as m
    left outer join MAKT as t
      on m.matnr = t.matnr
      and t.spras = 'E'
  {
    key m.matnr,
        m.mtart,
        t.maktx as description
  }
  where m.mtart = 'FERT';

Migration Benefits:

  • Better integration with SAP UI5
  • OData service generation
  • Analytics integration
  • Semantic metadata support
  • Easier maintainability
  • Better performance (smart execution)
  • Built-in security support
  • Associations and compositions
  • Calculated fields
  • Parameter support
Migration Path
Plan migration in phases. Run old and new views in parallel. Test thoroughly before cutover.

Debugging & Troubleshooting

Diagnose CDS issues

Debugging Techniques
Tools and methods for troubleshooting
// Test view with parameters
select * from Z_MATERIAL_V(p_mtart => 'FERT')
  where rownum <= 10;

// Check compilation errors
// HANA Studio → SQLScript → Right-click view → Check syntax

// Debug view definition
// SELECT * FROM SYS.VIEWS 
// WHERE VIEW_NAME = 'Z_MATERIAL_V';

// Check association navigation
select from Z_ORDER_HIERARCHY_V {
  vbeln,
  kunnr,
  items.posnr,        // Navigate association
  items.matnr
} where vbeln = '0000123456';

// Monitor performance
// HANA Studio → SQL Analyzer → Paste query → Analyze

// Check execution plan
EXPLAIN SELECT * FROM Z_MATERIAL_V
  WHERE mtart = 'FERT';

// View execution statistics
// HANA Cockpit → SQL Statements → Find view query

// Debug type issues
// Check field types at definition point
// Hover in Studio to see inferred types

// Test expressions
// Create test view with calculation
define view Z_TEST_CALC as
  select from MARA {
    key matnr,
        cast(1000 as decimal(10,2)) * 1.19 as result
  };

// Enable debug output (development only)
set option connection_context = 'DEBUG_MODE=ON';

// View dependencies
// HANA Studio → Repository → View dependencies graph

// Check for circular references
// HANA Studio → Editors → Validate CDS model
Pro Debugging
Use SAP HANA Studio's SQL Editor to test queries before implementing views. Always check the execution plan for large queries.
Additional Resources
For more HANA learning resources, visit our SAP HANA Documentation and explore CDS Views Deep Dive Module.