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

xe55xuns  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(438)

这只是我第二次使用堆栈溢出,所以对于如何更好地格式化我的问题,我愿意接受任何建设性的批评。
我有一个订单列表,我想创建一个有用的客户信息表。
我已经创建了一个新的表来标识唯一的客户(只使用一个选择的客户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
jei2mxaa

jei2mxaa1#

下面是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

如果要应用于您问题中的示例数据(我假设您的产品是字符串数据类型)

WITH `project.dataset.table` AS (
  SELECT 'Andy' name, '1'  product UNION ALL
  SELECT 'Bill', '2' UNION ALL
  SELECT 'Cole', '2' UNION ALL
  SELECT 'Andy', '2' UNION ALL
  SELECT 'Bill', '1' UNION ALL
  SELECT 'Cole', '2' UNION ALL
  SELECT 'Dave', '3' 
)

结果是

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`
))
uinbv5nw

uinbv5nw2#

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

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;

你也可以使用 logical_or() :

select name,
       logic_or(product = 1) as has_1,
       logic_or(product = 2) as has_2,
       logic_or(product = 3) as has_3
from t
group by name;

相关问题