Preferably, SQL would look more like:
FROM Foo f
WHERE f.value < 10
JOIN Bar b on b.id = f.bar_id
WHERE b.other_value > 20
SELECT f.group, f.value
GROUP BY f.group the_group AGGREGATING SUM(f.value) the_sum
WHERE the_sum > 100
ORDER BY the_group
And so on. FROM introduces a source of data which flows into the next line. SELECT does a projection, GROUP BY applies aggregation operators on groups and also does a projection. WHERE could be inserted pretty much anywhere. From(foo) |>
Where(Get.value .< 10) |>
Join(From(bar) |> As(:bar), on = Get.bar.id .== Get.bar_id) |>
Where(Get.bar.other_value .> 20) |>
Select(Get.group, Get.value) |>
Group(Get.group) |>
Where(Agg.sum(Get.value) .> 100) |>
Order(Get.group)
There is no HAVING and the you can use any tabular operators in any order. Aggregates are also separated from grouping and can be used in any context after Group is applied.
Let me know any feedback — as you can see it's still at the proposal stage. If it gains some traction I'll write an implementation.