clickhouse FixString和string的比较差异

发布时间 2024-01-06 23:26:54作者: 若-飞

有个clickhouse表,存储tx_hash字段:

有个语句统计tx_type:

SELECT 
			CASE tx_type
				WHEN 'created_nft' THEN 'created_nft_count'
				WHEN 'nft_transactions' THEN 'nft_transactions_count'
				WHEN 'chain_interaction' THEN 'chain_interaction_count'
			END AS attr_name,
			toString(COUNT(*)) AS attr_value
		FROM web3_data_count.Gameta_tx_hashes 
		GROUP BY user_address, tx_type

发现问题:如果tx_type是FixString类型那么无法得到attr_name, 但是如果tx_type是String类型将可以正常转换

 

在 ClickHouse 中,CASE 表达式的结果类型是根据其分支的返回类型来确定的。在你提供的查询语句中,CASE 表达式的分支返回的是字符串字面量,例如 'created_nft_count''nft_transactions_count''chain_interaction_count'

tx_typeFixedString(50) 类型时,它与字符串字面量进行比较时,将进行固定长度字符串的比较。由于字符串字面量的长度是小于等于 50 的,而 FixedString(50) 的长度是 50,因此 CASE 分支中的比较将始终返回 false,导致 attr_name 得到空值。

而当 tx_typeString 类型时,它与字符串字面量进行比较时,将按照字符串的内容进行比较。这种比较方式可以成功匹配到相应的分支,因此 attr_name 将得到预期的结果。

要解决这个问题,你可以在 CASE 表达式中使用 toString 函数将 tx_type 转换为字符串,以便与字符串字面量进行比较。例如:

sql
SELECT
    CASE toString(tx_type)
        WHEN 'created_nft' THEN 'created_nft_count'
        WHEN 'nft_transactions' THEN 'nft_transactions_count'
        WHEN 'chain_interaction' THEN 'chain_interaction_count'
    END AS attr_name,
    toString(COUNT(*)) AS attr_value
FROM web3_data_count.Gameta_tx_hashes
GROUP BY user_address, tx_type;

在上述示例中,我们使用 toString(tx_type)tx_type 转换为字符串,以确保与字符串字面量进行比较时能够匹配到相应的分支。这样,无论 tx_typeFixedString(50) 还是 String 类型,都能获得正确的 attr_name 值。

通过在 CASE 表达式中使用 toString 函数,你可以确保比较的类型一致,并获得预期的结果。