Often you join multiple table in SQL queries. What about XQuery, how can we perform joins in XQuery? This is what this third post in the XQuery for the SQL programmer series is all about.
A first example Assume you want to get all users with their bids. In SQL one could write, [cc lang="sql"]select u.NAME, b.ITEMNO, b.BID from USERS u, BIDS b where u.USERID = b.USERID[/cc] In XQuery this is expressed as follows, [cc lang="xquery"]for $user in collection("USERS")/USERS for $bid in collection("BIDS")/BIDS where $user/USERID = $bid/USERID return { $user/NAME, $bid/ITEMNO, $bid/BID }[/cc] Conceptually, the for-clauses of a FLWOR expression generate an ordered sequence of tuples of variable bindings. Note the analogy with a cartesian-join in SQL (a cross-join if you want). Next the where-clause filters the sequence of tuples. In our example above this results in the appropriate join condition being applied.Jack Sprat
1003 20
1007 200
Rip Van Winkle
...[/cc]
Suppose now you want to represent the results in a more tabular structure. This requires a bit more work in XQuery...Jack Sprat 1007 200
Rip Van Winkle [/cc]
You can fairly easy extend the last query to perform a full outer join. Only a matter of adding a third sub-expression. If you want to order the result by name and itemno, simply wrap the previous query with an additional FLWOR expression, [cc lang="xquery"]for $result in (for $user in collection("USERS")/USERS for $bid in collection("BIDS")/BIDS where $user/USERID = $bid/USERID return { $user/NAME, $bid/ITEMNO, $bid/BID } , for $user in collection("USERS")/USERS where fn:empty(collection("BIDS")/BIDS[USERID = $user/USERID]) return { $user/NAME }) order by $result/NAME return $result[/cc] What about subselects? In SQL we often use subselects. For example, get a list of all bids with the name of the bidder,[cc lang="xquery"]select (select u.NAME from USERS u where u.USERID = b.USERID), b.ITEMNO, b.BID from BIDS b[/cc]
Similar in XQuery you can write, [cc lang="xquery"]for $bid in collection("BIDS")/BIDS return { for $user in collection("USERS")/USERS where $user/USERID = $bid/USERID return $user/NAME, $bid/ITEMNO, $bid/BID }[/cc] Or more concise, [cc lang="xquery"]for $bid in collection("BIDS")/BIDS return { collection("USERS")/USERS[USERID = $bid/USERID]/NAME, $bid/ITEMNO, $bid/BID }[/cc] Suppose we want to order the bids by the bidder's name, [cc lang="sql"]select (select u.NAME from USERS u where u.USERID = b.USERID), b.ITEMNO, b.BID from BIDS b ORDER BY (select u.NAME from USERS u where u.USERID = b.USERID) [/cc]Rather than repeating the expression twice, use a let-clause in XQuery, [cc lang="xquery"]for $bid in collection("BIDS")/BIDS let $name := collection("USERS")/USERS[USERID = $bid/USERID]/NAME order by $name return { $name, $bid/ITEMNO, $bid/BID }[/cc] Similar to SQL, where you can use subselects at various locations in a select statement, this also applies to XQuery. FLWOR expressions can be nested. In fact, XQuery is much more open to this than SQL. Where in SQL a subselect can only be used in specific locations, in XQuery every expressions can be combined with any other expression. In SQL you have a rich set of functions, in our next post we'll compare this with the functions and operators available in SQL.View all posts from Marc Van Cappellen on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites