If you have such a big query and you doubt this would be changed in future, I'd recommend using Slick Plain SQL API because of 2 reasons:
- it is easier to implement
- some sort it's easier to support - cleaner view
Of course you'll loose compiler's time safety, but this might be non-critical if you are not going to change the query too often.
So the result would be:
Database.forURL("jdbc:h2:mem:humans", driver = "org.h2.Driver") withSession { implicit session =>
val sql = """
select a.id, a.name, count(*) as humans
from humans h1, areas a
where h1.gender = 'Female' and h1.area_id = a.id
group by area_id
having count(*) > (
select count(*)
from humans h2
where h2.gender = 'Male' and h1.area_id = h2.area_id
group by area_id
)
or not exists (
select *
from humans h2
where gender = 'Male' and h1.area_id = h2.area_id
group by area_id
)
"""
val result: (Long, String, Long) = StaticQuery.queryNA[(Long, String, Long)](sql).first()
//do something with the result
}