错误:Tableau中不存在功能regexp_matches(jsonb,unknown),但在其他地方可用

时间:2018-12-17 01:35:55

标签: sql regex postgresql tableau

我有一列名为“面包店活动”,其值都是如下所示的所有JSON:

{"flavors": [
    {"d4js95-1cc5-4asn-asb48-1a781aa83": "chocolate"},
    {"dc45n-jnsa9i-83ysg-81d4d7fae": "peanutButter"}], 
 "degreesToCook": 375, 
 "ingredients": {
    "d4js95-1cc5-4asn-asb48-1a781aa83": [
        "1nemw49-b9s88e-4750-bty0-bei8smr1eb", 
        "98h9nd8-3mo3-baef-2fe682n48d29"]
    },
 "numOfPiesBaked": 1,
 "numberOfSlicesCreated": 6
}

我正在尝试提取Tableau中使用正则表达式功能烘焙的馅饼的数量。具体来说,这个:

REGEXP_EXTRACT([Bakery Activity], '"numOfPiesBaked":"?([^\n,}]*)')

但是,当我尝试将此计算所得的字段放入文本表时,出现错误消息:

  

错误:函数regexp_matches(jsonb,unknown)不存在;

     

执行查询时出错

值得注意的是,我的数据源是PostgreSQL,Tableau regex函数支持该数据;并非我所有的条目都包含numOfPiesBaked;当我在模拟器中运行此命令时,我得到了正确的提取结果(实际上,我得到了"numOfPiesBaked": 1",但是删除字段名又是一个问题了)。

什么可能导致此错误?

2 个答案:

答案 0 :(得分:0)

简而言之:数据类型错误,函数错误,方法错误。

REGEXP_EXTRACT显然是abstraction layer of your client (Tableau),对于Postgres而言,它已翻译为regexp_matches()。但是该函数需要text输入。由于没有jsonb-> text的分配转换(有充分的理由),因此您必须添加一个显式的转换才能使其正常工作,例如:

SELECT regexp_matches("Bakery Activity"::text, '"numOfPiesBaked":"?([^\n,}]*)')

(第二个参数可以是无类型的字符串文字,Postgres函数类型的解析可以推迟适当的数据类型text。)

现代版本的Postgres也有regexp_match()返回一行(与regexp_matches不同),这似乎是更好的翻译

但是,正则表达式一开始是错误的方法
使用简单的json/jsonb operator ->>

SELECT "Bakery Activity"->>'numOfPiesBaked';

在您的示例中返回'1'
如果您知道该值是一个有效的整数,则可以立即将其强制转换为

SELECT ("Bakery Activity"->>'numOfPiesBaked')::int;

答案 1 :(得分:0)

我找到了一种在Tableau中处理JSONB数据的简便方法。 首先,从JSONB字段中计算字段,然后使用#include <iostream> #include <chrono> using namespace std::chrono_literals; class Peak { public: Peak (std::chrono::microseconds t, float magnitude) : t_(t), magnitude_(magnitude) { }; std::chrono::microseconds get_t() { return t_; } //have to comment this out or I get an error operator float() { return magnitude_; } operator std::chrono::microseconds() { return t_; } private: std::chrono::microseconds t_{2us}; float magnitude_; }; int main() { Peak a{3us, 100}; std::cout << "t is " << static_cast<std::chrono::microseconds>(a).count(); } 命令将该字段转换为字符串。 然后,在计算字段上,创建另一个计算字段并使用函数:

str([FIELD_name])

所需的键值对将构成第二个计算字段。