我对SQL和bigquery还是相当陌生,并且正在使用约140万行的数据集。
我当前感兴趣的值是category_name(字符串),item_id(字符串)。我感兴趣的是为category_name中的每个值计算不同的item_id(此列共有269个不同的值)。基本上在我的基本数据集中,每一行数据都包含一个item_id的实例,该实例以单个category_name出现,其中item_id可以根据当天出现的category_name的数量每天有多行。
我已经能够运行成功的查询,为category_name的每个值添加一个新列,用于显示不同item_id的值,现在最终输出应该是我不知道该怎么做的是为以下内容计算不同item_ids的百分比: 1个类别名称,也出现在其他所有类别名称中。因此,基本上,我正在寻找一个新列(如数据透视表),该列将对2个category_names的匹配item_ids进行计数,然后将该计数除以1 category_name中不同的item_id总数。因此,每个category_name本质上将有269个新列,并且每一行将代表基本category_name与其他category_name的重叠百分比。
[这是我当前感兴趣的表中的数据
category_name | item_id
---------------|------------
category1 | item1
category2 | item1
category3 | item1
category1 | item2
category4 | item2
category1 | item3
category5 | item3
category5 | item2
category6 | item4
category3 | item5
category3 | item6
category1 | item6
category2 | item5
category1 | item4
这是我当前的查询结果如下
category_name | distinct_items
---------------|-----------------
category1 | 5
category2 | 2
category3 | 3
category4 | 1
category5 | 2
category6 | 1
这是我希望最终输出看起来像的样子:
category_name | category1 | category2 | category3 | category4 | category5 | category6
--------------------------------------------------------------------------------------------------------
category1 | 100% | 20% | 40% | 20% | 40% | 20%
category2 | 50% | 100% | 100% | 0% | 0% | 0%
category3 | 66.67% | 66.67% | 100% | 0% | 0% | 0%
category4 | 100% | 0% | 0% | 100% | 100% | 0%
category5 | 100% | 0% | 0% | 50% | 100% | 0%
category6 | 100% | 0% | 0% | 0% | 0% | 100%
基本上,category_name的行值将是该category_name作为目标,并将它们的总distinct_items与其他category_names进行比较,并根据item_ids查找匹配项/总distinct_items的百分比。如果有另一种无需枢轴表来获得此输出的方法,也将不胜感激。上下文有269个category_names和6525个不同的item_ids。
[如果有一个更简单的公式,我可以在google data studio中使用此汇总,因为它在data studio中的最终输出应该是带有x和y轴的散点图,category_names和气泡为%重叠,所以也可以正常工作只需使用散点图可视化数据透视表结果即可。如果我的描述和问题中的任何内容没有意义或需要进一步说明,请随时为我添加标签,并让我知道造成混淆的地方。任何帮助是极大的赞赏!谢谢
您可以使用条件聚合:
select t.category_name,
countif( t2.category_name = 'category1' ) / count(*) as category1,
countif( t2.category_name = 'category2' ) / count(*) as category2,
countif( t2.category_name = 'category3' ) / count(*) as category3,
countif( t2.category_name = 'category4' ) / count(*) as category4,
countif( t2.category_name = 'category5' ) / count(*) as category5
from t join
t t2
on t.item = t2.item
group by t.category_name;
如果将值放在行而不是列中,这会更简单:
select t.category_name, t2.category_name,
count(*) / sum(count(*)) over (partition by t.category_name) as ratio
from t join
t t2
on t.item = t2.item
group by t.category_name, t2.category_name;
下面是BigQuery标准SQL的内容>>
步骤1
-动态生成查询文本,因此您无需手动输入所有269个类别...#standardSQL SELECT '''SELECT category_name, ''' || STRING_AGG(DISTINCT ' MAX(IF(category_name2 = "' || category_name || '", percent, NULL)) AS ' || category_name ) || ''' FROM ( SELECT t1.category_name, t2.category_name category_name2, ROUND(100 * COUNTIF(t1.item_id = t2.item_id) / COUNT(DISTINCT t1.item_id), 2) percent FROM `project.dataset.table` t1 CROSS JOIN `project.dataset.table` t2 GROUP BY t1.category_name, t2.category_name ) GROUP BY category_name ''' FROM `project.dataset.table`
如果您针对问题中的示例数据在上方运行-您将获得以下查询的拼合版本
-复制步骤1中的查询结果,然后将其作为查询运行-就这样!SELECT category_name, MAX(IF(category_name2 = "category1", percent, NULL)) AS category1, MAX(IF(category_name2 = "category2", percent, NULL)) AS category2, MAX(IF(category_name2 = "category3", percent, NULL)) AS category3, MAX(IF(category_name2 = "category4", percent, NULL)) AS category4, MAX(IF(category_name2 = "category5", percent, NULL)) AS category5, MAX(IF(category_name2 = "category6", percent, NULL)) AS category6 FROM ( SELECT t1.category_name, t2.category_name category_name2, ROUND(100 * COUNTIF(t1.item_id = t2.item_id) / COUNT(DISTINCT t1.item_id), 2) percent FROM `project.dataset.table` t1 CROSS JOIN `project.dataset.table` t2 GROUP BY t1.category_name, t2.category_name ) GROUP BY category_name
[步骤2
如果您将其应用于问题中的样本数据,则输出为
Row category_name category1 category2 category3 category4 category5 category6 1 category1 100.0 20.0 40.0 20.0 40.0 20.0 2 category2 50.0 100.0 100.0 0.0 0.0 0.0 3 category3 66.67 66.67 100.0 0.0 0.0 0.0 4 category4 100.0 0.0 0.0 100.0 100.0 0.0 5 category5 100.0 0.0 0.0 50.0 100.0 0.0 6 category6 100.0 0.0 0.0 0.0 0.0 100.0
注意1:您可以使用任何选择的客户端来自动化上述整个过程注意2:在您的简化示例中,我大部分都是根据数据来计算的。在实际情况下,您可能需要进行一些细微调整-如果对此有任何疑问-请发布新问题