Apama 10.15.0 | Developing Apama Applications | Developing Apama Applications in EPL | Working with Streams and Stream Queries | Defining stream queries | Joining two streams | Defining equi-joins with the join clause
 
Defining equi-joins with the join clause
An equi-join has a key expression for each of the two streams that are being joined. Two items are joined into an output item only if the values of their key expressions are equal. The full syntax for an equi-join, consisting of a from clause followed by a join clause, is:
from itemIdentifier1 in streamExpr1 [windowDefinition1]
   join itemIdentifier2 in streamExpr2 [windowDefinition2]
   on joinKeyExpr1 equals joinKeyExpr2
As with the partition and unique key expressions, each join key expression must return a comparable type (see Comparable types. Also, joinKeyExpr1 must include a reference to itemIdentifier1 and joinKeyExpr2 must include a reference to itemIdentifier2. Each join key may not refer to the item from the other stream. An example of an equi-join is:
from p1 in leftPairs retain 2
   join p2 in rightPairs retain 2
   on p1.letter equals p2.letter
   select sum(p1.num * p2.num);
This is illustrated in the following diagram:
Illustration of equi-joins
The query before the diagram corresponds to the aggregate projection. The three queries shown here are:
*Simple istream projection:
from p1 in leftPairs retain 2
   join p2 in rightPairs retain 2
   on p1.letter equals p2.letter
   select p1.num * p2.num
*Simple rstream projection:
from p1 in leftPairs retain 2
   join p2 in rightPairs retain 2
   on p1.letter equals p2.letter
   select rstream p1.num * p2.num
*Aggregate projection:
from p1 in leftPairs retain 2
   join p2 in rightPairs retain 2
   on p1.letter equals p2.letter
   select sum(p1.num * p2.num);
This diagram shows the input that was used in the cross-join example, but with the join changed to be an equi-join. As you can see, only the items with matching letters appear in the output. The first event on the right side of the join has the same letter as the event on the left, so an output is produced as before. When the second event arrives on the left, however, no output is produced, because the letter does not match the other side. When a b event arrives on the right side of the join, that is joined with the b event on the left.
Finally, at the end of the table you can see that the join is empty because none of the events on the left match any of the events on the right.
Here is a more concrete example of an equi-join:
from r in priceRequest
   join p in prices partition by p.symbol retain 1
   on r.symbol equals p.symbol
   select p.price
For each new stock price request, this query generates the latest price for that stock/symbol. In an equi-join, whenever an item enters a window on one side, the correlator evaluates the join condition to determine if the item matches any of the items in the window on the other side. The correlator joins and outputs each matching pair when it finds one.
Typically, you want to create a derived event that is a function of the events on both sides of the join operation. Here is another example:
from latest in latestSensorReadings
   join average in averageSensorReadings
   on latest.sensorId equals average.sensorId
   select SensorAlert(latest.sensorId, latest.value, average.mean) as alert{
send alert to "output";
}
This query joins a stream of the most recent readings from all the sensors with a stream of averages of the same readings over some period. When a new reading appears it causes an event on the stream of averages at the same time. This causes them to be joined to create an alert that contains both the latest value and the latest average, which is then sent.
See also IEEE special values in stream query expressions.