select event, event_time from events where event_date >= '2020-08-10' and event_date <= '2020-08-18' and event_time > 1597161600 limit 20; 前端展示1000条,下载可下载1000000条。
本表查询范围为:用户SSID/UUID、事件、事件属性、事件用户属性、all_value类型的用户属性与业务对象属性。
提示:event_params.xxx.yyy、user_profiles.xxx 、item_profiles.xxx.yyy三种字段建议起别名,否则查询可能存在问题。
本表查询范围为:用户SSID/UUID、all_value/last_value类型的用户属性。
本表查询范围为:all_value/last_value类型的业务对象相关信息
本表查询范围为:分群中包含的用户统计口径id、hash_uid、分群id等
*在"元数据"标签下,可以查看所有的分群名、分群id以及分群人数。
*当前暂不支持查询分群历史版本,因此目前通过分群id查询的是最近一次成功刷新的分群,和其他高级分析场景一致。
针对event_date与last_active_date,目前支持以下函数,如对其他函数有需求,可向客服反馈。
注意:当前自定义SQL查询不支持使用动态参数的方式进行SQL查询,例如:
select event, event_time from events where event = ‘app_launch’ and event_date = ${event_date} limit 20; --其中 event = ${event_name}这种动态参数由后续动态传入,此类动态参数形式的SQL查询,当前不支持
支持函数:
subtractMonths,subtractWeeks,subtractDays
addMonths, addWeeks, addDays
toStartOfQuarter,toStartOfMonth,toStartOfISOYear,toMonday,toStartOfWeek
备注:toStartOfWeek函数,mode为偶数时,起始为周一,否则为周日。
错误用法:
select event from events where toMonth(event_date) = 9; select event from events where subtractDays(event_date, 10) = '2021-09-20';
上述写法,自定义查询会提示无法推导出event_date。
正确用法:
select event from events where event_date >= subtractDays(today(), 10);
在任何情况下,都强烈建议采用event_date作为日期过滤条件,如需更加精确的时间区间,可采用event_date+event_time进行限制。
event_date表示事件发生的日期,精确到天,可用于加快查询速度,缺省时默认为过去7天(包含今天)。
目前仅支持“YYYY-MM-dd”的格式,例如:event_date='2020-08-10'。
event_time表示事件的发生时间,为10位时间戳,精确到秒,可用于提供更精确的时间区间。
国内站接入应用的event_date均为UTC+8(东八区)时间,国际站接入应用的event_date均为UTC(零时区)时间。
例如:
event_time = 1597273200,国内站event_date为'2020-08-13'
event_time = 1597273200,国际站event_date为'2020-08-12'
国内站接入应用: 查询北京时间2020年8月10日6:00至2020年8月12日14:00所发生的事件
select event from events where event_time >= 1597010400 and event_time <= 1597212000 and event_date >= '2020-08-10' and event_date <= '2020-08-12'
国际站接入应用,应用的时区为UTC时间: 查询UTC时间2020年8月10日6:00至2020年8月12日14:00所发生的事件
select event from events where event_time >= 1597039200 and event_time <= 1597240800 and event_date >= '2020-08-10' and event_date <= '2020-08-12'
国际站接入应用,应用的时区为UTC+7时间: 查询UTC+7时间2020年8月10日6:00至2020年8月12日14:00所发生的事件,相当于查询UTC时间2020年8月9日23:00至2020年8月12日7:00所发生的事件:
select event from events where event_time >= 1597014000 and event_time <= 1597215600 and event_date >= '2020-08-09' and event_date <= '2020-08-12'
注意:无论何时,都建议您在SQL中指定event_date的起、止时间,以此加速查询速度。如果您未添加,SQL自定义查询功能会自动拼装时间限制,可能会产生与您预计时间段不同的数据。
与events表进行join时,last_active_date可以通过event_date进行自动推导,其他情况建议用户指定last_active_date范围。
语义举例:
select user_profiles.gender from users where last_active_date >= '2020-08-10'
select gender, hash_uid, user_id from events as table_a left join ( select hash_uid, user_profiles.gender as gender from users where user_profiles.gender is not null ) as table_b on table_a.hash_uid == table_b.hash_uid where event_date <= '2020-08-10' and event = 'A' limit 500;
该sql未指定事件的起始event_date,因此默认起始event_date为今日的365天前,假设为'2019-10-11'。此时,join子句中,也默认查询last_active_date>='2019-10-11'的用户。
值得注意的是,该案例的典型错误写法为:
select gender, hash_uid, user_id from events as table_a left join ( select hash_uid, user_profiles.gender as gender from users where user_profiles.gender is not null where last_active_date <= '2020-08-10' ) as table_b on table_a.hash_uid == table_b.hash_uid where event_date <= '2020-08-10' limit 500;
如果用户填写last_active_date <= '2020-08-10',其join子句的语义就变为——查询2020年8月10号之后就没有事件的那些用户,而不是查询2020年8月10号之前有活动的用户。
quantile(level)(expr)
参数
median(expr)相当于是quantile(0.5)(expr)
注意: 该函数采用Reservoir_sampling随机算法,因此结果是近似且非确定的。
举例:查询2020年8月10日的订单事件中,分位数为0.2的金额。
select quantile(0.2)(event_params.order.money) from events where event = 'order' and event_date = '2020-08-10' limit 1;
计算 Σ((x - x̅)^2) / (n - 1)
,这里 n
是样本大小, x̅
是x
的平均值。
举例: 查询2020年8月10日的订单事件中,金额的方差
select varSamp(event_params.order.money) from events where event = 'order' and event_date = '2020-08-10' limit 1;
语法:
SELECT if(cond, then, else)
如果条件cond的计算结果为非零值,则返回表达式then的结果,并且跳过表达式else的结果(如果存在)。如果cond为零或NULL,则跳过then表达式的结果,并返回else表达式的结果(如果存在)。、
参数:
举例:查询2020年10月6日至12日中,触发A事件比触发B事件次数多的人。
select distinct user_unique_id
from (select user_unique_id as user_unique_id
,
if(event = 'A', count(1), 0) as event1_cnt
,
if(event = 'B', count(1), 0) as event2_cnt
from events
where event in ('A', 'B')
and event_date >= '2020-10-06'
and event_date <= '2020-10-12'
group by user_unique_id, event
limit 1000)
group by user_unique_id
having sum(event1_cnt) > sum(event2_cnt)
返回与源数组大小相同的数组,其中每个元素表示与其下标对应的原数组元素在原数组中出现的次数。常用用法类似hive中的开窗函数row_number()
参数:
举例:查询2020年10月25日至11月1日中,不同事件的前三次发生时间
select *
from (
select event, time_arr, row_number
from (
select event,
groupArray(time) as time_arr,
arrayEnumerate(time_arr) as row_number
from (select distinct event, event_time as time
from events
where event_date >= '2020-10-25'
and event_date <= '2020-11-01'
order by time) a
group by event
)
array join
time_arr
, row_number
)
where row_number <= 3;
结果集:
event | time_arr | row_number |
---|---|---|
wechat_unsubscribe | 1603967567 | 1 |
wechat_unsubscribe | 1603968269 | 2 |
wechat_unsubscribe | 1603968275 | 3 |
goods_detail_view | 1603469824 | 1 |
goods_detail_view | 1603473124 | 2 |
goods_detail_view | 1603479424 | 3 |
补充:
该用法类似于HQL的row_number(),在上述例子中的HQL写法为:
select *
from
(
select event,
row_number() over(partition by event order by event_time) as row_number
from events
) a
where a.row_number <= 3;
类似函数:
arrayEnumerateUniq、arrayEnumerateDense
match(haystack, pattern)
举例:
select distinct user_profiles.user_id, multiMatchAny(user_profiles.user_id, ['^[0-9]*$', '^\d{10}$']) as is_match from events where event_date > '2021-03-01' limit 20;
结果集:
user_profiles.user_id | is_match |
---|---|
209041 | 1 |
unknown | 0 |
multiMatchAny(haystack, [pattern1, pattern2, ...])
multiMatchAnyIndex(haystack, [pattern1, pattern2, ...])
举例:
select distinct user_profiles.user_id, multiMatchAnyIndex(user_profiles.user_id, ['^[0-9]*$', '^([a-zA-Z0-9_-]\.)+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$', '(\.[a-zA-Z0-9_-]@)+']) as regex_index from events where event_date > '2021-03-01' limit 2;
结果集:
user_profiles.user_id | regex_index |
---|---|
209041 | 1 |
3 | |
2 | |
unknown | 0 |
select event from events where user_profiles.user_id = 'datafinder@datarangers.com' and event_date = '2020-08-10' limit 20
select count(event) from events where event = 'event_name' and event_time > 1596988800 and event_time < 1597161600 limit 20
select count(distinct hash_uid) from events where (event = 'event_1' or event = 'event_2' and event != 'event_3') and event_time > 1596988800 and event_time < 1597161600 limit 20
select user_profiles.user_id, event_params.{event_name}.{event_param_name} from events where event = 'sogo' and event_date > '2020-01-01' order by event_time desc limit 10;
select case when amount > 10 then 'x>10' when amount >5 and amount <= 10 then '5<x<=10' else 'x<=5' end from ( select event_params.buy.amount as amount from events where event = '`buy`' and event_date > '2020-06-01' and event_date < '2020-08-02' limit 200 )
select event from events where hash_uid in (select hash_uid from cohorts where cohort_id = 154) and event_date = yesterday()
select user_id from users where hash_uid in (select hash_uid from cohorts where cohort_id = 154) and last_active_date >= '2021-01-01'
函数详见:https://clickhouse.com/docs/zh/sql-reference/functions/
错误 | 严重程度 | 修改建议 | |
---|---|---|---|
请增加 WHERE 子句,否则查询可能会超时。 | 中 | 增加WHERE子句,否则默认查询过去7日的数据。 | |
缺少 event_time 或 event_date 时间限定,默认查询过去7日的数据。 | 中 | WHERE子句中增加event_date或event_time条件,否则默认查询过去7日的数据。 | |
发现多条SQL,只有第一条会执行。 | 中 | 将需要执行的SQL语句放于第一条,或注释掉其他SQL。(支持/ ** /多行注释与--单行注释。) | |
存在SQL不支持的的字符,已忽略。 | 中 | 删除SQL查询里不支持的字符。 | |
缺少 LIMIT 子句,最多返回1000条。 | 中 | 增加LIMIT子句。 | |
查询结果最多返回1000条。 | 中 | LIMIT子句限制在1000以内。 | |
表名 {table_name} 不正确,请检查您的SQL。 | 高 | 表名修改为events | |
仅支持查询过去 365 天的数据,超出这个范围的数据将不会被查询。 | 中 | 将查询时间限定为近365天。 | |
您查询的数据不在过去365天之间。 | 高 | 将查询时间限定为近365天。 | |
最多支持 20 条join子句,请检查您的 SQL。 | 高 | 降低JOIN子句数量 | |
仅支持 SELECT 语句,请检查您的 SQL。 | 高 | 仅保留SELECT语句。 | |
没有查询语句,请检查您的 SQL。 | 高 | ||
不支持 SELECT * 查询,请检查您的 SQL。 | 高 | 仅查询需要查询的列。 | |
不支持超过10层的子查询,请检查您的 SQL。 | 高 | 降低子查询层数。 | |
查询的列名 {column} 不存在,请检查您的 SQL。 | 高 | 检查列名 {column} 是否在数据表中。 | |
最多支持对30列进行 GROUP BY,请检查您的 SQL。 | 高 | 降低GROUP BY后列的数量。 | |
不支持表函数 {table_function} ,请检查您的 SQL。 | 高 | 将表名改为events | |
存在不支持的函数 {function_name} ,请检查您的SQL。 | 高 | 查询该 {function_name} 是否在支持的函数列表中,如果您需要使用该函数,请联系客服。 | |
不支持SETTINGS,请检查您的 SQL。 | 中 | 删除SETTINGS语句,否则默认忽略。 | |
查询存在错误: {error_message} | 高 | 根据 {error_message} 修改您的SQL语句。 | |
最多支持 3 条UNION ALL子句,请检查您的 SQL。 | 高 | 降低UNION ALL子句数量 | |
不支持INTO OUTFILE, 请检查您的SQL。 | 高 | 删除INTO OUTFILE子句。 | |
不支持FORMAT, 请检查您的SQL。 | 高 | 删除FORMAT子句。 | |
不支持的时间条件 {time_condition}, 请检查您的SQL。 | 高 | event_time时间条件请用整型10位时间戳,event_date时间条件请用“YYYY-MM-dd”,e.g. “2020-08-01”。 | |
查询并发量超过限制。 | 高 | 降低查询的并发量。如果您有更大的并发需求,请联系客服。 | |
SQL存在语法错误: {syntax_error_msg}。 | 高 | 根据详细的语法错误信息对SQL语句进行修正。 | |
请使用 event_time 作为事件发生时间,而不是{time_condition}。 | 高 | 采用event_time作为事件发生时间。 | |
请使用{new_column}代替{old_column}。 | 中 | 高 | 由于技术升级或其他原因,可能会提供代替old_column的新列new_column。 |
时间条件不合法 (详情: {cause})。 | 高 | 未写或时间条件存在问题,比如event_date>='2020-08-05' and event_date='2020-08-01' | |
举例:时间条件不合法 (详情: 时间限制推导为空)。 | |||
无法推导出{target_condition},请补充{target_condition}限制条件。 | 高 |
| |
举例:无法推导出event_date,请补充event_date限制条件。 |
| ||
请为{column}起个别名,否则可能查询报错。 | 中 | 对于user_profiles.xxx、event_param.xxx.yyy、item_profiles.xxxx.yyy等列,建议起别名,否则可能存在错误。 |
错误码 | 错误信息 | 常见错误原因 | |||||
---|---|---|---|---|---|---|---|
215 | xxxxxx is not under aggregate function and not in GROUP BY | SQL的查询列不在GROUP BY中,比如: | |||||
select event, user_profiles.user_id from events group by event; | |||||||
将其修改为: | |||||||
select event, user_profiles.user_id from events group by event, user_profiles.user_id; | |||||||
或者: | |||||||
select event, any(user_profiles.user_id) from events group by event; | |||||||
43 | Illegal types of arguments (xxx, yyy)of function [equals | greater | greaterOrEquals | less | lessOrEquals | notEquals ] | 比较符的两边不是同一个类型,比如: |
事件buy的price属性类型为int,此时应将 | |||||||
select event from events where event_param.buy.price != '1'; | |||||||
将其修改为: | |||||||
select event from events where event_param.buy.price != 1; | |||||||
53 | ARRAY JOIN requires array argument | 类型不匹配,比如: | |||||
select arrayJoin(event_params.force.$target_uuid_list) | |||||||
62 | Syntax error: failed at position xxxx | 查看详细报错,比如: | |||||
select event from events where event as e = 'app_launch' limit 20; | |||||||
报错信息为: | |||||||
查询存在错误: code: 62, detail_message: DB::ExceptionDB::Exception: Syntax error: failed at position 239: = 'app_launch' ) and ( tea_app_id = 41514 and event_date >= '2021-03-09' and event_date <= '2021-03-15' ) limit 20 ;. Expected one of: token, Comma. | |||||||
观察后发现,报错发生在**= 'app_launch'** 周围,排查后发现,event as e语法有误,应改为: | |||||||
select event from events where event = 'app_launch' limit 20; | |||||||
202 | Too many simultaneous queries. | 当前数据库查询繁忙,请稍后再试。 | |||||
42 | Number of arguments for function xxxx doesn't match | 参数个数不匹配,比如: | |||||
select least(user_profiles.user_id) from events limit 20; | |||||||
报错信息为: | |||||||
查询存在错误: code: 42, detail_message: DB::ExceptionDB::Exception: Number of arguments for function least doesn't match: passed 1, should be 2. | |||||||
查询手册后发现least函数需要2个参数,返回两个参数中较小的值。 | |||||||
*具体函数用法可查阅 https://clickhouse.tech/docs/v19.14/zh/ |
查询2020年8月1号后的活跃用户的国家id:
select user_profiles.loc_country_id from users where last_active_date > '2020-08-01' limit 200;
用户属性列名的格式为user_profiles.{user_profile_name}。
事件属性列名的格式为event_params.{event_name}.{event_param_name} 。样例如下:
select user_profiles.os_name, event_params.app_launch.session_duration, network_type, device_brand, event_time from events and event_date >= '20200812' and event_date <= '20200819' limit 20;
注意:尽管样例SQL中的WHERE条件内,没有含有event = 'app_launch',但是根据
event_params.app_launch.session_duration的字段语义,仍然只会查询app_launch事件下的session_duration属性值。
如果您需求查询不同事件下的同一个属性名的属性值,请联系客服。
在 DataRangers 的“数据管理”功能中可以查看。
在数据表中搜索"event_params",可以查看所有的事件与事件属性的对应关系。
业务对象属性列名格式为item_profiles.{item_name}.{item_param_name}。样例如下:
select item_profiles.book.name, item_profiles.book.authors, item_profiles.phone.price from items limit 30;
查询业务对象为book的名称和作者、查询业务对象为phone的价格。与查询事件属性类似,样例SQL中并没有指定item_name in ('book', 'phone'),但是根据item_profiles.book.authors等字段的语义,自定义查询功能会自动推导item_name,因此样例SQL等价于如下SQL:
select item_profiles.book.name, item_profiles.book.authors, item_profiles.phone.price from items where item_name in ('book', 'phone') limit 30;
可通过hash_uid进行事件表与用户表的JOIN。样例如下:
select gender, hash_uid, user_id from events as table_a left join ( select hash_uid, user_profiles.gender as gender from users where user_profiles.gender is not null ) as table_b on table_a.hash_uid == table_b.hash_uid where event_date <= '2020-08-10' and event = 'A' limit 500;
注意点:推荐使用hash_uid进行JOIN,通过其他字段JOIN可能导致查询超时。
可以通过event_params对应事件的xxx_hash_item_id与items表对应业务对象的hash_item_id做JOIN查询。样例如下:
select event_params.buy.book_hash_item_id as book_item_id, event_params.buy.browser as buy_browser, item_table.book_name, from events event_table any inner join (select hash_item_id, item_profiles.book.name as book_name, from items where item_name = 'book') item_table on arrayJoin(if(isNotNull(event_params.buy.book_hash_item_id), assumeNotNull(event_params.buy.book_hash_item_id), [NULL])) = item_table.hash_item_id where event_date > '2020-12-10' limit 20;
上述样例的作用为:查询buy事件关联的业务对象属性为book时,浏览器的值以及书的名字。
注意点:
arrayJoin(if(isNotNull(event_params.buy.book_hash_item_id), assumeNotNull(event_params.buy.book_hash_item_id), [NULL]))
将Array类型的book_hash_item_id转换为标量,方便JOIN。
$is_first_day属性为虚拟事件属性,Finder查询侧会根据用户事件发生时间和用户首次时间发生时间做比较来计算$is_first_day的属性值。如果您需要查询,可以参考如下SQL:
select (toStartOfDay(toDateTime(event_time, 'Asia/Shanghai')) == toStartOfDay(toDateTime(ut.first_event_time, 'Asia/Shanghai'))) as `$is_first_day` from events et global any inner join ( select hash_uid, user_profiles.first_event_time as first_event_time from users ) ut on et.hash_uid == ut.hash_uid where event = 'browse' and event_date >= '2020-12-22' and event_date <= '2020-12-28';
select toUInt32((event_time - toUnixTimestamp('2020-12-22', 'Asia/Shanghai')) / 86400) as t, count(1) as cnt from events et global any inner join ( select hash_uid, user_profiles.first_event_time as first_event_time from users ) ut on et.hash_uid == ut.hash_uid where event = 'browse' and event_date >= '2020-12-22' and event_date <= '2020-12-28' and (toStartOfDay(toDateTime(event_time, 'Asia/Shanghai')) == toStartOfDay(toDateTime(ut.first_event_time, 'Asia/Shanghai'))) group by t order by t ;
因为行为细查中,会将uuid转化为ssid查询,因此既能查出实名的,也能查出匿名的行为。但是在自定义查询中,sql中如果给定了user_id=xxx,那就只会查询实名行为,不会查询匿名行为。
自定义查询目前不支持“新老用户”、虚拟属性、虚拟事件和圈选事件。
替代方案有:
事件公共属性通常以如下形式出现:
event_params.any_event.公共属性名 event_params.any_active_event.公共属性名 event_params.事件名.公共属性名 event_params.公共属性名
当查询下述sql时,查询的范围为所有事件。
select event_params.any_event.common_param_a from events; 或者 select event_params.common_param_a from events;
当查询下述sql时,查询的范围为所有主动事件。
select event_params.any_active_event.common_param_a from events;
当查询下述sql时,查询的范围为事件event_1。
select event_params.event_1.common_param_a from events;
上述sql等价为——
select event_params.any_event.common_param_a from events where event = 'event_1';
如果一条sql中包含event_params.any_event.xxx、event_params.any_active_event.xxx、event_params.具体事件名.xxx中的多个,那么查询的事件限制规则如下:
条件 | 规则 |
---|---|
sql中包含event_params.事件名.公共属性名 | 自动推导事件名作为限制,多个具体事件名之间是or的关系 |
sql中包含event_params.any_active_event. 公共属性名 | 限制主动事件。 |
sql中包含event_params.any_event. 公共属性名 | 不限制事件。 |
规则之间是or的关系,举例说明:
字段 | 推导的事件查询限制 |
---|---|
any_event下的事件公共属性a, | 无限制 |
any_active_event下的公共属性a, | |
event_1下的公共属性a | |
any_active_event下的公共属性a, | event_1或event_2或者主动事件 |
event_1下的公共属性a | |
event_2下的公共属性a | |
event_1下的公共属性a | event_1或event_2 |
event_2下的公共属性a | |
any_event下的事件公共属性a, | 无限制 |
any_active_event下的公共属性a, | |
any_event下的事件公共属性a, | 无限制 |
event_1下的公共属性a | |
event_2下的公共属性a |
使用event_param.事件属性名,这样自定义查询将不会自动拼装事件限制,需要您在where条件中指定事件,比如:
select event_params.url as url from events where event in ('event_1', 'event_2') and event_date = today();
注意:如果包含该属性的事件较多,可能导致SQL解析耗时增多。
当前自定义SQL查询不支持使用动态参数的方式进行SQL查询,例如:
select event, event_time from events where event = ‘app_launch’ and event_date = ${event_date} limit 20; --其中 event = ${event_name}这种动态参数由后续动态传入,此类动态参数形式的SQL查询,当前不支持