Skip to content

Compare BQL and SQL Commands

Although BQL is similar to existing database query languages like SQL, its custom design for Measure IQ queries means that it differs in a few key points.

The following table compares and identifies differences between BQL and SQL clauses.

ConceptSQLBQLNotes
select *select * from my_tableNot supported
select count(*)select count(*) from my_tableselect count(*) from my_table
select distinctselect count(distinct user) from my_tableselect count_unique(user) from my_tableUse “select count_unique” instead of “select count distinct”.
whereselect count(*) from my_table where user = “jack”select count(* where user=”jack”) from my_tableIn BQL, “where” used as a filter is contained within an aggregation. This is because you can have multiple aggregations, each with its own set of filters.
and, or, notselect count(*) from my_table where not(user = “jack” or user = “jill”)select count(* where not(user=”jack” or user=”jill”)) from my_table
order byselect count(distinct purchase) from my_table order by user ascselect count_unique(purchase) as purchases, user from my_table order by purchases asc
min, max, avg, count, sumselect min(time_in_app) from my_tableselect min(time_in_app) from my_table
inselect count(*) from my_table where user in (“jack”,”jill”)select count(* where user in (“jack”,”jill”)) from my_table
betweenselect count(*) from my_table where user_id between 1 and 100select count(*) from my_table between 2019-2-19 and nowBQL between is specifically a Measure IQ timespec syntax. BQL does not support “between” as a regular operator, and SQL lacks the notion of timespec.
group byselect count(*),country from my_table group by countryselect count(*) from my_table group by user between 2014-2-19 4pm and now”group by” corresponds to “split by” in the Measure IQ UI.
limitselect count(*) from my_table limit 5select count(*) from my_table group by user limit 5 between 2014-2-19 4pm and now

select count(*) from my_table group by user, country limit 5 and by platform limit 3
BQL can use hierarchical “group by”, as shown in the second example here. The syntax, though, is the same from SQL to BQL.
joinsselect my_table.user, lookup_table.age from inner join my_table.user = lookup_table.userNot supportedBQL does not support “joins” because they are implied depending on the property combinations.
havingselect count(user), country from my_table group by country having count(user) > 5Not supported
on scopeNot supportedselect count(* on event) from my_table group by Actor(max(age))

select count(* on Actor) from my_table group by Actor(max(age))
Explicitly specify the scope of an aggregation.


The first query counts the number of events grouped by the user’s age.

The second query counts the number of users grouped by the user’s age. This is the same as:

select count(*) from my_table group by Actor(max(age))
math (round, sqrt, etc.)select count(user) from my_table where sqrt(age)>5select count_unique(user where sqrt(age) > 5) from my_table
percentileselect distinct month, P90 = percentile_disc(0.9) within group (order by score) over (partition by [month]) from my_tableselect percentile(user_high_score, 90) from my_tablePercentile is similar to percentile_desc in relational databases, but the two functions are not exactly the same, hence the different name.
beginning_of_time,
for every
Not supportedselect count(*) from my_table for every week over 7 days between beginning_of_time and nowSome powerful time operators are present in BQL but not in SQL. This example counts the number of events that happened in a 7 day period, and performs this calculation every week from the beginning of time to now.
likeselect count(*) from my_table where name like ‘%jack%’select count(* where name like ‘.*jack.*’) from my_tableBQL “like” searches for text contained within a column. It is similar to mysql “rlike”. It accepts regular expressions, unlike SQL “like”, which accepts %foo% syntax.