在SQL中将分类列转换为二进制表示形式

在SQL中将分类列转换为二进制表示形式,sql,google-bigquery,Sql,Google Bigquery,假设在包含分类数据的表中有一列字符串数组。有没有一种简单的方法可以转换这个模式,这样就有很多类别布尔列表示该类别列的二进制编码 例如: id type ------------- 1 [A, C] 2 [B, C] 转换为: id is_A is_B is_C 1 1 0 1 2 0 1 1 我知道我可以“手工”完成,即使用: WITH flat AS (SELECT *

假设在包含分类数据的表中有一列字符串数组。有没有一种简单的方法可以转换这个模式,这样就有很多类别布尔列表示该类别列的二进制编码

例如:

id      type
-------------
1       [A, C]
2       [B, C]
转换为:

id    is_A     is_B    is_C
1     1        0       1
2     0        1       1
我知道我可以“手工”完成,即使用:

WITH flat AS (SELECT * FROM t, unnest(type) type),
mid AS (SELECT id, (type='A') as is_A, (type='B') AS is_B, (type='C') as is_C)
SELECT id, SUM(is_A), SUM(is_B), SUM(is_C) FROM mid GROUP BY id
但我正在寻找一种解决方案,当类别数在1-10K左右时,该解决方案会起作用 顺便说一下,我正在使用BigQuerySQL

正在寻找一种在类别数约为1-10K时有效的解决方案

下面是BigQuerySQL的示例

第1步-动态生成与问题中使用的查询类似的查询-但现在它是基于您的表-yourTable动态构建的

标准SQL 在类别为的情况下,从表中选择不同的cat,将UNNESTtype设置为cat 选择CONCAT 将类别设置为从表中选择不同的cat,将UNNESTtype设置为cat, id作为从表中选择不同的id, 配对作为选择id,从id交叉连接类别分类, 选择id为平面,从表中选择cat,取消选择类型cat, 组合为, 选择p.id,p.cat作为列,IFf.cat为空,0,1作为标志, 从p为左的对到f为平的对, 在p.cat=f.cat和p.id=f.id上, , 选择id, 字符串_aggcontsumifcol=',cat',flag,0原样uu,cat按cat排序, 从组合中, 按id分组, 按id订购 作为疑问 从类别 步骤2-复制上述查询的结果,将其粘贴回Web UI并运行查询

我想你有主意了。Yo可以像上面那样在SQL中实现它,也可以在您选择的任何客户机中生成最终查询


我曾尝试过这种生成查询的方法,但在Python中,问题是在BigQuery中,查询很容易达到256KB的查询大小限制

首先,让我们看看达到256KB的限制有多“容易” 假设你有10个字符作为类别的平均长度——在这种情况下,你可以用这种方法覆盖大约4750个类别。 平均20人,覆盖率约为3480人,30-2750人

如果您要通过删除空格和AS等方式稍微压缩sql,则可以分别进行压缩: 5400、3800、2970分别用于10、20、30个字符

所以,我会说——是/同意——在实际情况中,它很可能在5公里之前达到极限

所以,第二,让我们看看这是否真的是一个大问题! 举个例子,假设您需要6K个类别。让我们看看,假设3K场景按照初始解决方案工作,如何将其拆分为两个批次 我们需要做的是将类别划分为两个组-仅基于类别名称 因此,第一组将在“cat1”和“cat3000”之间 第二组为–介于“cat3001”和“cat6000”之间

因此,现在使用temp1和temp2表作为目标运行Step1和Step2两个组 在步骤1中-添加到查询的最底部-来自类别之后

猫在“cat1”和“cat3000”之间的位置 第一批,以及

其中cat介于“cat3001”和“cat6000”之间 第二批

现在,继续执行步骤3

第3步-合并部分结果

标准SQL 选择*例外2 从temp1完全连接 选择id作为id2,*temp2除外 ON id=id2 -按id订购 您可以使用以下简单/虚拟数据测试最后一个逻辑

以temp1为例 选择1作为id,1作为当前值,0作为当前值 选择2作为id,0作为\u A,1作为\u B UNION ALL 选择3作为id,1作为A,0作为B , temp2 AS 选择1作为id,1作为C,0作为全部 选择2作为id,1作为C,0作为全部 选择3作为id,0作为C,1作为D 上述产品很容易扩展到两个以上批次

希望这有帮助

正在寻找一种在类别数约为1-10K时有效的解决方案

下面是BigQuerySQL的示例

第1步-动态生成与问题中使用的查询类似的查询-但现在它是基于您的表-yourTable动态构建的

标准SQL 在类别为的情况下,从表中选择不同的cat,将UNNESTtype设置为cat 选择CONCAT 将类别设置为从表中选择不同的cat,将UNNESTtype设置为cat, id作为从表中选择不同的id, 配对作为选择id,从id交叉连接类别分类, 选择id为平面,从表中选择cat,取消选择类型cat, 组合为, 选择p.id,p.cat作为列,IFf.cat为空,0,1作为标志, 从p为左的对到f为平的对, 在p.cat=f.cat和p.id=f.id上, , 选择id, 字符串_aggcontsumifcol=',cat',flag,0原样uu,cat按cat排序, 从组合中, 按id分组, 按id订购 作为疑问 从类别 步骤2-复制上述查询的结果,将其粘贴回Web UI并运行查询

我想你有主意了。Yo可以像上面那样在SQL中实现它,也可以生成最终查询 在您选择的任何客户中


我曾尝试过这种生成查询的方法,但在Python中,问题是在BigQuery中,查询很容易达到256KB的查询大小限制

首先,让我们看看达到256KB的限制有多“容易” 假设你有10个字符作为类别的平均长度——在这种情况下,你可以用这种方法覆盖大约4750个类别。 平均20人,覆盖率约为3480人,30-2750人

如果您要通过删除空格和AS等方式稍微压缩sql,则可以分别进行压缩: 5400、3800、2970分别用于10、20、30个字符

所以,我会说——是/同意——在实际情况中,它很可能在5公里之前达到极限

所以,第二,让我们看看这是否真的是一个大问题! 举个例子,假设您需要6K个类别。让我们看看,假设3K场景按照初始解决方案工作,如何将其拆分为两个批次 我们需要做的是将类别划分为两个组-仅基于类别名称 因此,第一组将在“cat1”和“cat3000”之间 第二组为–介于“cat3001”和“cat6000”之间

因此,现在使用temp1和temp2表作为目标运行Step1和Step2两个组 在步骤1中-添加到查询的最底部-来自类别之后

猫在“cat1”和“cat3000”之间的位置 第一批,以及

其中cat介于“cat3001”和“cat6000”之间 第二批

现在,继续执行步骤3

第3步-合并部分结果

标准SQL 选择*例外2 从temp1完全连接 选择id作为id2,*temp2除外 ON id=id2 -按id订购 您可以使用以下简单/虚拟数据测试最后一个逻辑

以temp1为例 选择1作为id,1作为当前值,0作为当前值 选择2作为id,0作为\u A,1作为\u B UNION ALL 选择3作为id,1作为A,0作为B , temp2 AS 选择1作为id,1作为C,0作为全部 选择2作为id,1作为C,0作为全部 选择3作为id,0作为C,1作为D 上述产品很容易扩展到两个以上批次


希望这对您有所帮助。

您尝试过吗?您尝试过吗?我尝试过这种生成查询的方法,但在Python中,问题是查询很容易达到BigQuery中查询大小的256KB限制。@S.Mohsensh-请参阅我的补充answer@S.Mohsensh-如果我的回答帮助了你,你也接受了。已经做到了:o。请参阅@MikhailBerlyant中的更多at和Upvote部分。多年后,我找到了这个答案,这对我帮助很大。谢谢我曾尝试过这种生成查询的方法,但在Python中,问题是在BigQuery.@S.Mohsensh中,查询很容易达到查询大小的256KB限制-请参阅我的answer@S.Mohsensh-如果我的回答帮助了你,你也接受了-请你也考虑投票,除非你已经这样做了:O。请参阅@MikhailBerlyant中的更多at和Upvote部分。多年后,我找到了这个答案,这对我帮助很大。谢谢