play.html,可通过任意 ClickHouse HTTP 端口的 /play 路径访问) 支持按结果列排序、按列值筛选以及分页浏览结果,无需编辑查询。
这些操作均不在浏览器中执行。每次更改都会使用相应的查询构建设置重新运行查询;服务器会将查询包装为派生表,并在外层添加 ORDER BY、WHERE 和 LIMIT,以物化该设置。因此,屏幕上显示的是整个查询排序、筛选和分页后的结果,而非仅重新排列当前页面恰好包含的行。
排序
aria-sort) 。
在具有可悬停指针 (鼠标) 的设备上,只有在鼠标悬停于列标题上或某个箭头获得焦点时才显示箭头,避免平时造成干扰;在不支持悬停的触摸设备及其他粗指针设备上,箭头会始终显示,以便直接点按。参与排序的列即使未悬停也会显示两个箭头:一个让排序状态一目了然,另一个则是因为反转排序方向最可能是下一步操作。
列标题中的每个图标,无论控制哪项功能,显示方式都一致:当该功能未在该列生效时,图标会以低调的颜色显示;一旦生效,便会采用为已生效控件保留的颜色——浅色主题中为洋红色,深色主题中为黄色——并且即使不悬停也会保持显示。低调显示仅减弱色彩,绝不降低透明度,因此图标无论显示在列名上还是单元格的颜色编码上,都不会显得褪色。
按多个列排序
ORDER BY 使用的顺序——第一个键决定排序,后续每个键用于打破前面键的并列情况。当排序键多于一个时,每个活动箭头还会以右上角标显示其列在该顺序中的位置 (▼¹、▲²、…) 。
对于已是排序键的列,按住 Shift 只会改变其排序方向,并保留其在排序顺序中的位置。取消某列的排序只会移除该列,其他键将保持不变。
筛选
通过列标题筛选
> 10,字符串列为 LIKE '%test%'。输入框在标题单元格内展开,单元格会增加第二行以容纳它;设置过滤器后,过滤器本身也显示在这一行,因此可以在查看过滤器的位置直接编辑它。输入内容为列名后的部分,因此 > 10 会变为 WHERE column > 10,服务器在此处接受的任何表达式都可以使用——BETWEEN 1 AND 5、IN (1, 2, 3)、IS NOT NULL、% 2 = 0。
按下应用按钮 (或 Enter) 会应用过滤器并重新运行查询;按 Esc,或在其他任何位置点击或切换选项卡,都会放弃编辑并收起输入框。没有内容可应用时,应用按钮会处于禁用状态——即未设置过滤器的列中显示空输入框时;但对于已设置过滤器的列,即使输入框为空,应用按钮仍保持可用,因为清空输入框后再应用即可移除该过滤器。多个列上的过滤器会通过 AND 组合。
从单元格筛选
选择其中一项会立即生效。日期、时间或枚举将与服务器呈现的原始文本比较,ClickHouse 会将其解析回该列的类型 (枚举则解析为值的名称) 。
contains 会转换为 LIKE 模式,并对值中的 % 和 _ 进行转义,因此会按字面值匹配。值不属于上述类型的单元格——数组、元组、map 或长文本——不会提供菜单;但仍可通过列标题中的输入框筛选该列。
当前生效的过滤器
分页
page 设置,然后重新运行查询;服务器会将页码转换为相应的 OFFSET。只要结果仍处于分页状态,分页器就会一直显示,即使每页都恰好填满、不再看起来像被截断。
不会显示总页数,因为总页数未知——统计结果行数意味着需要运行第二个查询。分页器会列出当前页前的十页、当前页和下一页,后面跟着 …。点击 … 会将其变为可输入任意页码的输入框;输入框失去焦点时会采用输入的页码 (按 Enter 也会使其失去焦点) 。
仅当当前页已填满时,才会提供下一页。若返回的行数少于该页可容纳的行数,则表示已到达结果末尾,后面不会再有下一页。 (如果结果长度恰好是页面大小的整数倍,仍会提供额外一页,但该页会返回空结果:要区分这种情况,同样需要统计行数。)
Per page 显示每页包含的行数,编辑方式相同:点击该值并输入另一个值。它不能超过结果一次可显示的行数——更大的页面会返回随后被表格截断的行,而下一页会从这些行之后开始,因此继续分页会悄然跳过那些从未显示的行;如果输入更大的数值,会按该最大值处理,显示的也将是该值。更改它后会从第一页重新开始,因为采用新大小的页面会包含不同的行。
更改排序或任何过滤器都会回到第一页:两者都会改变结果包含哪些行或行的顺序,因此用户原先所在的页面不再表示结果中的同一部分。
应用方式
order、filter、limit 和 page 查询构建设置发送。由于服务器会将它们应用于已解析的查询,而非查询文本,因此无论原查询为何种形式,它们都能与之配合使用:UNION、尾随的 FORMAT 子句以及查询自身的 ORDER BY 和 LIMIT 均可正常工作,编辑器中的查询也绝不会被重写。
列名会以带引号的标识符形式传递,因此名称为表达式 (count()) 或包含空格的结果列也可作为排序或过滤键。
何时可用
SELECT 和 UNION 查询 (包括以 WITH 子句或 FROM 开头的查询) 。SHOW、DESCRIBE、EXISTS 或 EXPLAIN 不支持此功能:这些语句确实会产生表,但相关设置不适用于它们,因此在此提供控件会暗示行具有实际上并不具备的结果。
形态调整仅适用于单条语句的结果,因此不适用于“全部运行”这种多语句执行;其中每条语句都是具有各自列的独立查询。
对于第一页最多只有一行的结果,也不提供此功能:单行无论如何排序都是相同的顺序,过滤器只能保留或移除该行,因此这些控件除了重新运行查询以获取相同的行外无能为力——而空结果甚至没有可移除的行。这也是在此处隐藏颜色编码开关的原因:最多只有一行时,没有可比较的内容。
两类单行结果会保留控件,因为在这些情况下,控件是唯一的恢复途径:
- 已排序或已应用过滤器的结果,其排序必须保持可逆,过滤器必须能够清除——匹配单行的过滤器正是长结果变为短结果的方式,若同时移除控件,用户就会被困在启用该过滤器的状态;
- 因显示限制而被截断的结果,即较长结果的第一页:页面大小受表一次可显示的单元数量限制,因此非常宽的结果可能被截断为单行,而其后的行正是排序和分页用于访问的内容。
ORDER BY 或 WHERE 应用于新语句可能不存在的列。
它也属于运行该语句时的上下文:所选数据库、发送请求的服务器和用户,以及查询参数的值。更改其中任一项后,相同的文本会指向不同的列——例如切换数据库后的 SELECT * FROM events,或编辑参数后的 SELECT * FROM {tbl:Identifier}——因此也会丢弃该形态,下一次运行将返回未经形态调整的结果。
下载和复制
持久化
sort_columns、filters、page 和 page_size) 、浏览器历史记录以及各查询选项卡的结果快照中,因此重新加载页面、共享链接或前进后退时都会保留该形态。由于形态决定了结果行,而不仅仅是其呈现方式,自动运行查询 (run=1) 的共享链接会以相同的形态重新运行查询,从而复现结果本身。为保持精简,仅会存储活跃的形态——未应用形态的结果不会向 URL 或历史记录状态添加任何内容。
如上所述,恢复的结果会将其形态绑定到生成该结果的上下文:快照会记录生成这些行时所使用的数据库、连接和参数值,因此更改其中任一项后重新运行语句时,会丢弃该形态,而不会将其应用于不同的结果。
与颜色编码模式和固定列一样,形态会按查询选项卡分别保存,因此在一个选项卡中对结果进行排序或筛选,不会重新运行另一个选项卡中的结果。
限制
- 如果服务器无法应用某种形态,查询将失败,错误会像其他失败的查询一样显示。随后会丢弃该形态,因为失败后既不会显示可用于清除它的列标题,也不会显示分页器。
- 排序和筛选通过结果中的列名识别列。结果中可能会两次出现相同的列名 (
SELECT 1 AS x, 2 AS x,或联接了具有相同列名的表) ,这类列无法仅凭名称区分,因此不会提供排序或筛选控件;同一结果中列名唯一的列仍保留这些控件。 - 多列排序需要按住 Shift 键,因此在触摸设备上不可用;单列排序不受此限制。
- 单行结果的垂直 (转置) 布局没有列标题,因此也没有控件;因此,用户已调整过形态的结果会保留其水平布局。