• 使用ABAP CDS views 创建一个分析模型


    参考blog

    1,Create an analytical model based on ABAP CDS views
    https://blogs.sap.com/2018/03/18/create-an-analytical-model-based-on-abap-cds-views/

    2,Create a Multi-Dimensional Report from an Analytical Query
    https://developers.sap.com/tutorials/s4hana-kut-create-multi-dimensional-report.html

    3,Define the Analytical Query CDS View
    https://blogs.sap.com/2017/02/26/step-2-define-the-analytical-query-cds-view/

    4,How to create custom Fiori Multidimensional Reporting Application in S/4HANA on-premise
    https://blogs.sap.com/2018/07/11/how-to-create-custom-fiori-multidimensional-reporting-application-in-s4hana-on-premise/


    数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing)、联机分析处理OLAP(On-Line Analytical Processing)。
    OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。
    https://www.cnblogs.com/beyondstorm/archive/2006/08/12/475011.html

    SAP HANA将OLAP和OLTP处理结合在一个内存数据库中,事务和分析可以同时存在,这意味着可以实时访问所需的准确信息。因为我们将事务和分析世界合并在一个数据库中,所以在基于ABAP CDS(核心数据服务)构建的数据模型时,开发的方式会有一些不同。


    当您需要利用聚合的优势跨不同区域(例如按时间、按位置、按负责人)公开结果时,建议使用分析模型进行报告。这些模型建立在事实(Facts )和维度(Dimensions )之上,这些视图包含用于进行详细分析和获得业务价值的基本数据。

    以销售报告为例,它提供基于客户、产品、日期和销售人员的结果。事实(Fact )就是销售本身,它包含我们可以测量的价值(例如销售额和总销售额),根据客户、产品、时间和销售人员的过滤器是维度(Dimensions ),这些维度可以附加属性(Attributes )或文本(Texts )(例如客户名称、地址和产品描述),当我们将所有这些维度连接起来时,我们就有了一个多维数据集(Cube ),从而准备了一个分析模型用于消费。

    在这个分析模型的基础上,我们需要构造一个查询(Query ),以我们希望向用户公开的方式调整数据。多维数据集必须能够被一些不同的查询重用和使用。
    例如,使用上面的销售模型,我们可以在不同的查询中生成以下指标:

    • Sales by year quarter;
    • Sales by products with cost above $100;
    • Sales by customer located in a specific city;
    • Average of sales amount per number of sales;
    • Uplift on sales from prior year.

    每个查询将实现特定的目的,并且可以针对不同的应用程序(例如报告、kpi等)进行设计。


    CDS的主要目的之一是允许创建语义丰富的数据模型,而注释是支持这项任务的主要组件。

    有许多不同领域的注解,可以通过下面的link进行查看。(注解太难了。资料太少了。)
    https://help.sap.com/viewer/cc0c305d2fab47bd808adcad3ca7ee9d/7.5.9/en-US/630ce9b386b84e80bfade96779fbaeec.html

    使用abap cds view来创建分析模型,需要使用到cds view的注解:Analytics、AnalyticsDetails。
    Analytics 提供了对ABAP CDS视图的支持,并支持利用数据聚合来使用多维数据。
    AnalyticsDetails支持通过更改聚合行为、计划或公式来计算度量,从而调整分析查询布局。只能在@Analytics.query : true的情况下使用。

    如果想要声明维度、事实、聚合级别或多维数据集,必须在CDS视图的头部包含以下注释:

    @Analytics.dataCategory: #VALUE

    可以将 #VALUE 替换成下面的项目

    • #CUBE
    • #AGGREGATIONLEVEL
    • #DIMENSION
    • #FACT

    因为Cubes必须包含至少一个可度量的属性,要将字段定义为可度量的,需要将此注释放在字段的顶部:

    @DefaultAggregation: #SUM

    也可以更改默认聚合,最常见的组合是使用 #SUM 进行聚合

    另外需要使用以下注解

    @Analytics.query: true

    因为定义了聚合模式,查询必须从多维数据集中(cubes)选择数据,否则会返回错误。


     我们以下面的数据模型,进行开发。


    创建各个维度的cds view。

    1,创建package

    2,创建cdsview



    DIMENSION: Airline

    @AbapCatalog.sqlViewName: 'ZDIMEAIRLINE'
    @AbapCatalog.compiler.compareFilter: true
    @AccessControl.authorizationCheck: #CHECK
    @EndUserText.label: 'Airline'
    
    @Analytics.dataCategory: #DIMENSION
    
    define view Z_Dimension_Airline
      as select from scarr
    {
          @ObjectModel.text.element: [ 'AirlineName' ]
      key carrid   as Airline,
      
          @Semantics.text: true
          carrname as AirlineName,
          
          @Semantics.currencyCode: true
          currcode as Currency
    } 

    DIMENSION: Connection

    @AbapCatalog.sqlViewName: 'ZDIMECONNECT'
    @AbapCatalog.compiler.compareFilter: true
    @AccessControl.authorizationCheck: #CHECK
    @EndUserText.label: 'Flight Connection'
    
    @Analytics.dataCategory: #DIMENSION
    
    @ObjectModel.representativeKey: 'FlightConnection'
    
    define view Z_Dimension_Connection
      as select from spfli
      association [0..1] to Z_Dimension_Airline as _Airline on $projection.Airline = _Airline.Airline
    {
          @ObjectModel.foreignKey.association: '_Airline'
      key carrid                    as Airline,
    
          @ObjectModel.text.element: [ 'Destination' ]
      key connid                    as FlightConnection,
    
          @Semantics.text: true
          concat(cityfrom,
            concat(' -> ', cityto)) as Destination,
    
          _Airline
    } 

    DIMENSION: Customer

    @AbapCatalog.sqlViewName: 'ZDIMECUSTOMER'
    @AbapCatalog.compiler.compareFilter: true
    @AccessControl.authorizationCheck: #CHECK
    @EndUserText.label: 'Flight Customer'
    
    @Analytics.dataCategory: #DIMENSION
    
    define view Z_Dimension_Customer
      as select from scustom
      association [0..1] to I_Country as _Country on $projection.Country = _Country.Country
    {
          @ObjectModel.text.element: [ 'CustomerName' ]
      key id      as Customer,
    
          @Semantics.text: true
          name    as CustomerName,
    
          @ObjectModel.foreignKey.association: '_Country'
          @Semantics.address.country: true
          country as Country,
    
          @Semantics.address.city: true
          city    as City,
          
          _Country
    } 

    DIMENSION: Travel Agency

    @AbapCatalog.sqlViewName: 'ZDIMETRVAGENCY'
    @AbapCatalog.compiler.compareFilter: true
    @AccessControl.authorizationCheck: #CHECK
    @EndUserText.label: 'Travel Agency'
    
    @Analytics.dataCategory: #DIMENSION
    
    define view Z_Dimension_TravelAgency
      as select from stravelag
      association [0..1] to I_Country as _Country on $projection.Country = _Country.Country
    {
          @ObjectModel.text.element: [ 'TravelAgencyName' ]
      key agencynum as TravelAgency,
    
          @Semantics.text: true
          name      as TravelAgencyName,
    
          @ObjectModel.foreignKey.association: '_Country'
          @Semantics.address.country: true
          country   as Country,
    
          @Semantics.address.city: true
          city      as City,
          
          _Country
    } 

    1. @AbapCatalog.sqlViewName:指定sqlview的名称,可以在se11中查询到。
    2.@AbapCatalog.compiler.compareFilter:在cdsview的路径表达式中定义筛选条件的计算。
    3.@AccessControl.authorizationCheck:使用DCL进行权限的检查。
    4. @EndUserText.label:元素的短文本。
    5. @Analytics.dataCategory: #DIMENSION:所有的维度有需要有该分类。
    6. @ObjectModel.text.element:与文本名称进行关联。
    7. @ObjectModel.foreignKey.association:外部属性关联,使用该注解。
    8. @ObjectModel.representativeKey:组合主键,定义一个代表键。
    9. @Semantics:帮助定义字段类型。

    准备好所有的维度之后,创建cube。
    CUBE: Flight Bookings

    @AbapCatalog.sqlViewName: 'ZCUBEFLIGHTBOOK'
    @AbapCatalog.compiler.compareFilter: true
    @AccessControl.authorizationCheck: #CHECK
    @EndUserText.label: 'Flight Bookings'
    
    @Analytics.dataCategory: #CUBE
    
    define view Z_Cube_FlightBookings
      as select from sbook
      association [0..1] to I_CalendarDate           as _CalendarDate on  $projection.FlightDate = _CalendarDate.CalendarDate
      association [0..1] to Z_Dimension_Airline      as _Airline      on  $projection.Airline = _Airline.Airline
      association [0..1] to Z_Dimension_Connection   as _Connection   on  $projection.Airline          = _Connection.Airline
                                                                      and $projection.FlightConnection = _Connection.FlightConnection
      association [0..1] to Z_Dimension_Customer     as _Customer     on  $projection.Customer = _Customer.Customer
      association [0..1] to Z_Dimension_TravelAgency as _TravelAgency on  $projection.TravelAgency = _TravelAgency.TravelAgency
    {
      /** DIMENSIONS **/
    
      @EndUserText.label: 'Airline'
      @ObjectModel.foreignKey.association: '_Airline'
      carrid                 as Airline,
    
      @EndUserText.label: 'Connection'
      @ObjectModel.foreignKey.association: '_Connection'
      connid                 as FlightConnection,
    
      @EndUserText.label: 'Flight Date'
      @ObjectModel.foreignKey.association: '_CalendarDate'
      fldate                 as FlightDate,
    
      @EndUserText.label: 'Book No.'
      bookid                 as BookNumber,
    
      @EndUserText.label: 'Customer'
      @ObjectModel.foreignKey.association: '_Customer'
      customid               as Customer,
    
      @EndUserText.label: 'Travel Agency'
      @ObjectModel.foreignKey.association: '_TravelAgency'
      agencynum              as TravelAgency,
    
      @EndUserText.label: 'Flight Year'
      _CalendarDate.CalendarYear,
    
      @EndUserText.label: 'Flight Month'
      _CalendarDate.CalendarMonth,
    
      @EndUserText.label: 'Customer Country'
      @ObjectModel.foreignKey.association: '_CustomerCountry'
      _Customer.Country      as CustomerCountry,
    
      @EndUserText.label: 'Customer City'
      _Customer.City         as CustomerCity,
    
      @EndUserText.label: 'Travel Agency Country'
      @ObjectModel.foreignKey.association: '_TravelAgencyCountry'
      _TravelAgency.Country  as TravelAgencyCountry,
    
      @EndUserText.label: 'Travel Agency Customer City'
      _TravelAgency.City     as TravelAgencyCity,
    
      /** MEASURES **/
    
      @EndUserText.label: 'Total of Bookings'
      @DefaultAggregation: #SUM
      1                      as TotalOfBookings,
    
      @EndUserText.label: 'Weight of Luggage'
      @DefaultAggregation: #SUM
      @Semantics.quantity.unitOfMeasure: 'WeightUOM'
      luggweight             as WeightOfLuggage,
    
      @EndUserText.label: 'Weight Unit'
      @Semantics.unitOfMeasure: true
      wunit                  as WeightUOM,
    
      @EndUserText.label: 'Booking Price'
      @DefaultAggregation: #SUM
      @Semantics.amount.currencyCode: 'Currency'
      forcuram               as BookingPrice,
    
      @EndUserText.label: 'Currency'
      @Semantics.currencyCode: true
      forcurkey              as Currency,
    
      // Associations
      _Airline,
      _CalendarDate,
      _CalendarDate._CalendarMonth,
      _CalendarDate._CalendarYear,
      _Connection,
      _Customer,
      _Customer._Country     as _CustomerCountry,
      _TravelAgency,
      _TravelAgency._Country as _TravelAgencyCountry
    } 

    1. 不用必须使用cube去构造fact数据集,可以直接公开在cube中定义的表,来避免使用过多的层级。fact视图不能有连接或者关联,只包含可度量的值,如果要连接维度,要使用cube而不是fact。
    2. @Analytics.dataCategory: #CUBE:所有的cube需要使用该分类。
    3. @DefaultAggregation:该字段用来进行度量。
    4. 所有关联都暴露在视图的底部,以便在查询使用期间提供对属性和文本的访问。

    使用tcode(RSRTS_ODP_DIS)。该事务用于检查放置在分析数据模型中的关联、文本和层次结构,为每个属性提供详细的分析。
    将创建的sqlviewname放入odp name中,点击执行。

     

    消费view,进行query

    QUERY: Flight Bookings

    @AbapCatalog.sqlViewName: 'ZQUERYFLIGHTBOOK'
    @AbapCatalog.compiler.compareFilter: true
    @AccessControl.authorizationCheck: #CHECK
    @EndUserText.label: 'Flight Bookings'
    
    @Analytics.query: true
    @VDM.viewType: #CONSUMPTION
    
    define view Z_Query_FlightBookings
      as select from Z_Cube_FlightBookings
    {
        /** DIMENSIONS **/
        
        @AnalyticsDetails.query.display: #KEY_TEXT
        @AnalyticsDetails.query.axis: #FREE
        Airline, 
        @AnalyticsDetails.query.display: #KEY_TEXT
        @AnalyticsDetails.query.axis: #FREE
        FlightConnection, 
        @AnalyticsDetails.query.display: #KEY
        @AnalyticsDetails.query.axis: #FREE
        FlightDate, 
        @AnalyticsDetails.query.display: #KEY_TEXT
        @AnalyticsDetails.query.axis: #FREE
        Customer, 
        @AnalyticsDetails.query.display: #KEY_TEXT
        @AnalyticsDetails.query.axis: #FREE
        TravelAgency, 
        @AnalyticsDetails.query.display: #KEY
        @AnalyticsDetails.query.axis: #FREE
        CalendarYear,
        @AnalyticsDetails.query.display: #TEXT
        @AnalyticsDetails.query.axis: #FREE
        CalendarMonth,
        @AnalyticsDetails.query.display: #TEXT
        @AnalyticsDetails.query.axis: #FREE
        CustomerCountry,
        @AnalyticsDetails.query.display: #KEY
        @AnalyticsDetails.query.axis: #FREE
        CustomerCity,
        @AnalyticsDetails.query.display: #TEXT
        @AnalyticsDetails.query.axis: #FREE
        TravelAgencyCountry,
        @AnalyticsDetails.query.display: #KEY
        @AnalyticsDetails.query.axis: #FREE
        TravelAgencyCity,
        @AnalyticsDetails.query.display: #KEY
        @AnalyticsDetails.query.axis: #FREE
        Currency,
        @AnalyticsDetails.query.display: #KEY
        @AnalyticsDetails.query.axis: #FREE
        WeightUOM,
        
        /** MEASURES **/
        
        TotalOfBookings, 
        WeightOfLuggage,
        BookingPrice,
        
        @EndUserText.label: 'Average Weight Per Flight'
        @AnalyticsDetails.exceptionAggregationSteps.exceptionAggregationBehavior: #AVG
        @AnalyticsDetails.exceptionAggregationSteps.exceptionAggregationElements: [ 'Airline', 'FlightConnection', 'FlightDate' ]
        @AnalyticsDetails.query.formula: '$projection.WeightOfLuggage'
        @AnalyticsDetails.query.decimals: 0
        0 as AverageWeightPerFlight
    } 

    可以用一般的sql语句对view进行查询。
    SELECT SUM("Quantity") FROM "MyProducts" WHERE "Product_Name" IN ('Jackets', 'Coats');

    1. 所有的query需要设置@Analytics.query: true
    2. @AnalyticsDetails用于进行查询,提供以下功能:
      @AnalyticsDetails.query.display: #KEY_TEXT:设置显示key还是text。i.e EmployeeName for Employee.            
      @AnalyticsDetails.query.axis:定位元素的轴
      @AnalyticsDetails.exceptionAggregationSteps.exceptionAggregationBehavior:进行例外聚合运算
      @AnalyticsDetails.exceptionAggregationSteps.exceptionAggregationElements:进行例外聚合运算时,使用的列
      @AnalyticsDetails.query.formula:计算公式
      @AnalyticsDetails.query.decimals:小数点位数

    3,测试查询结果

    登陆friori管理页面,建立tile与对应的target

    tile

    target

    Semantic Object、action要与tile的值设置为一致。
    URL、ID需要指定为固定的值。
    参数中的,XQUERY,需要设置为上面实现的sqlviewname加前缀2C。XSYSTEM需要设置为LOCAL,我感觉是需要与segw中的service maintenance中设置的一致。
    其他的一些参数可以参照最上面的blog。

    之后登陆fiori launchpad点击tile进入。

  • 相关阅读:
    C#多线程编程之:集合类中Synchronized方法与SyncRoot属性原理分析
    Newtonsoft.Json 序列化和反序列化 以及时间格式 2 高级使用
    C++:基类和派生类
    C++:友元(非成员友元函数、成员友元函数、友元类)
    C++:静态成员
    C++:向函数传递对象(对象、对象指针、对象引用)
    C++:常类型Const
    C++:对象的赋值和复制
    C++:类的组合
    C++:析构函数
  • 原文地址:https://www.cnblogs.com/suoluo119/p/11678681.html
Copyright © 2020-2023  润新知