Skip to content

EQL How To

01es edited this page Oct 18, 2017 · 5 revisions

Q1: How to translate into EQL the following SQL:

SELECT * FROM ROTMAST WHERE ROTABLE_NO IN (SELECT ROTABLE_NO FROM STI_ROTABLE_STAT)

A1: First convert the SQL to use the EXISTS clause:

SELECT * FROM ROTMAST R WHERE EXISTS (SELECT * FROM STI_ROTABLE_STAT S WHERE S.ROTABLE_NO = R.ROTABLE_NO)

Then create EQL sub-query:

final EntityResultQueryModel<RotableEo> subQuery = 
      select(RotableEo.class).where().prop("rotable").eq().extProp("id").model();

Then create main query:

final EntityResultQueryModel<Rotable> rotableQuery = 
      select(Rotable.class).where().exists(subQuery).model();

A1 (less optimal alternative):

final EntityResultQueryModel<Rotable> subQuery = 
      select(RotableEo.class).yield().prop("rotable").modelAsEntity(Rotable.class);

final EntityResultQueryModel<Rotable> mainQuery = 
      select(Rotable.class).where().prop("id").in(subQuery);

But of course rewritten sql in A1 should be more performant!



Q2: How to make calculated boolean properties that simply check the existence of something in the database.

A2: Let's have a look at an example of an EQL model for boolean calculated property in entity Person that determines whether some person is a "delegated certification manager" based on the presence of current delegations. Delegations are considered "current" if the current date/time (now) is between fromDate and toDate.

The most natural approach to building the required EQL model is to use a caseWhen expression. The main question here is what condition should the caseWhen be based on.

One possible answers is to check if the number of the current delegations for a person is greater than zero. This is illustrated below.

protected static final ExpressionModel delegatedCertificationManager_ = expr()
            .caseWhen()
            .model(select(Delegation.class)
                   .where().prop("toPerson").eq().extProp("id")
                     .and().prop("fromDate").le().now()
                     .and().begin().prop("toDate").isNull().or().prop("toDate").ge().now().end().
                   yield().countAll().modelAsPrimitive()
             ).gt().val(0)
            .then().val(true)
            .otherwise().val(false).endAsBool().model();

Unfortunately, this is a very inefficient approach -- count is computationally intensive, and we don't really need the actual number of delegations. Instead, we're simply interested in the fact whether there is at least one delegation.

In order to avoid heavy computations in this case, count should be replaced with a test on existence of relevant delegations. Interestingly enough the use of exists is a lot more precise and direct answer to the question of "existence". The model below utilises exists for the caseWhen condition -- it is both more concise (there is no comparison) and much faster to execute.

            
protected static final ExpressionModel delegatedCertificationManager_ = expr()
             .caseWhen()
             .exists(select(Delegation.class)
                     .where().prop("toPerson").eq().extProp("id")
                       .and().prop("fromDate").le().now()
                       .and().begin().prop("toDate").isNull().or().prop("toDate").ge().now().end().model())
             .then().val(true)
             .otherwise().val(false).endAsBool().model();
Clone this wiki locally