如何在一个SQL查询中分组不同的值和计算字段

如何在一个SQL查询中分组不同的值和计算字段,sql,group-by,google-bigquery,boolean,calculated-field,Sql,Group By,Google Bigquery,Boolean,Calculated Field,这只是我第二次使用堆栈溢出,所以我愿意接受任何关于如何更好地格式化问题的建设性批评 我有一个订单列表,我想创建一个有用的客户信息表 我创建了一个新的表,用于标识唯一的客户(仅使用一组精选的客户ID),但我不确定是否有合适的函数可以准确地对他们进行分组,并根据他们附带的字段生成布尔值 我需要新字段显示一个布尔值,表示客户的订单是否针对特定的产品SKU 假设这是源表 NAME | PRODUCT ------------ Andy | 1 Bill | 2 Cole | 2 Andy | 2 Bil

这只是我第二次使用堆栈溢出,所以我愿意接受任何关于如何更好地格式化问题的建设性批评

我有一个订单列表,我想创建一个有用的客户信息表

我创建了一个新的表,用于标识唯一的客户(仅使用一组精选的客户ID),但我不确定是否有合适的函数可以准确地对他们进行分组,并根据他们附带的字段生成布尔值

我需要新字段显示一个布尔值,表示客户的订单是否针对特定的产品SKU

假设这是源表

NAME | PRODUCT
------------
Andy | 1
Bill | 2
Cole | 2
Andy | 2
Bill | 1
Cole | 2
Dave | 3
我希望输出只对每个名称具有唯一的值,并带有一个布尔值,显示给定名称的任何记录是否已收到该产品

NAME | HAS1 | HAS2 | HAS3
--------------------------
Andy | true | true | false
Bill | true | true | false
Cole | false | true | false
Dave | false | false | true

您可以使用聚合和简单逻辑:

select name,
       countif(product = 1) > 0 as has_1,
       countif(product = 2) > 0 as has_2,
       countif(product = 3) > 0 as has_3
from t
group by name;
您还可以使用:


下面是BigQuery标准SQL

如果您预先知道产品名称(例如示例中的“1”、“2”、“3”),并且产品名称很少,那么您可以使用下面的简单版本

#standardSQL
SELECT name,
  MAX(product = '1') AS has1,
  MAX(product = '2') AS has2,
  MAX(product = '3') AS has3
FROM `project.dataset.table`
GROUP BY name   
如果要应用于您问题中的样本数据(我假设您的产品在这里是字符串数据类型)

结果是

Row name    has1    has2    has3     
1   Andy    true    true    false    
2   Bill    true    true    false    
3   Cole    false   true    false    
4   Dave    false   false   true       
如果事先不知道产品名称和/或产品数量,则可以使用以下版本

EXECUTE IMMEDIATE '''
SELECT name,''' || (
  SELECT STRING_AGG(DISTINCT "MAX(product = '" || product || "') AS has" || product)
  FROM `project.dataset.table`
) || '''  
FROM `project.dataset.table`
GROUP BY name
'''   
输出完全相同

正如您在这里看到的,整个查询是动态组装的,所以您不需要担心产品的数量和名称

下面的版本与上面的版本相同,但更易于管理/阅读

EXECUTE IMMEDIATE FORMAT('''
SELECT name, %s 
FROM `project.dataset.table`
GROUP BY name
''', (
  SELECT STRING_AGG(DISTINCT "MAX(product = '" || product || "') AS has" || product)
  FROM `project.dataset.table`
))

在询问之前,您是否尝试过这样搜索?像这样的问题已经有很多答案了!是的!不幸的是,我很难找到答案…非常感谢!
EXECUTE IMMEDIATE '''
SELECT name,''' || (
  SELECT STRING_AGG(DISTINCT "MAX(product = '" || product || "') AS has" || product)
  FROM `project.dataset.table`
) || '''  
FROM `project.dataset.table`
GROUP BY name
'''   
EXECUTE IMMEDIATE FORMAT('''
SELECT name, %s 
FROM `project.dataset.table`
GROUP BY name
''', (
  SELECT STRING_AGG(DISTINCT "MAX(product = '" || product || "') AS has" || product)
  FROM `project.dataset.table`
))