Here's a breakdown of the leaders of the pack on this front[0]
Haskell
1) Opaleye[1]: composable and prevents invalid sql, but no join support (simulated via sub selects), Postgres only, and tough syntax to parse.
2) Esqueleto[2]: composable, readable, supports joins, but Postgres only, and the DSL can't/doesn't prevent invalid sql (which is, IIRC, one of the reasons why Opaleye came into being).
Scala
1) Slick[3] myriad databases supported (Oracle and SQL Server require non-free license), join support, fully composable (really, king of monad hill), and elegant syntax (until you `groupBy`/`sortBy` and then enter unreadble tuple_.1, tuple._N soup). Also, grouping requires flattening result set via min, max, sum, etc. aggregate function so not possible to return tuple representing say, a User, when grouping. Suggested workaround is to group on the client (and send a million rows over the wire to app server, ok o_O).
2) Squeryl[4] myriad databases supported (all free), join support, sql-like syntax, but lacks compositionality of aforementioned and relies on runtime reflection to make the DSL go.
Microsoft
LINQ to SQL/Objects myriad databases supported (not sure of driver licensing), excellent sql-like syntax, and type providers straight other worldly, but lacks compositionality and is tied to Windows (until *nix support lands).
[0] There are likely (many) others but these are the statically typed ones I'm aware of. Feel free to add others, curious to see what's out there (e.g. OCaml must have something)
[1] https://github.com/tomjaguarpaw/haskell-opaleye
[2] https://github.com/prowdsponsor/esqueleto