【问题标题】:Pivot Table in Google Big QueryGoogle Big Query 中的数据透视表
【发布时间】:2018-07-14 03:58:09
【问题描述】:

我需要计算所有对 A、B、C、D 唯一的 ID。所以 "A"/"A" , "B"/"B","C"/"C", "D"/"D" - 应该给我 A,B,C,D 独有的 ID 计数。 而 "A"/"B" 和 "B"/"A"- 将是 ID,其位置为 A 和 B。类似地,"A"/"C" 和 "C"/"A" = 将是 ID,其具有放置为A和C。ID在两个地方的重叠。计数需要随着每次重叠而不断增加请有人建议。我有一张如下表

ID     Place
1       A
2       B
1       C
6       B
4       D
5       A
6       C
7       A
8       A
8       C

你能指导我想出以下输出吗

   A B C D
A  2 0 2 0
B  0 1 1 0
C  2 1 0 0
D  0 0 0 1

【问题讨论】:

  • 您应该解释构建该矩阵的逻辑!否则你很可能会得到更多的反对票,最重要的是没有机会得到我们的帮助 - 所以请编辑你的问题并提供更多细节
  • 对此我深表歉意。逻辑:-“A”/“A”、“B”/“B”、“C”/“C”、“D”/“D”——应该给我 A、B、C、D 唯一的 ID 计数.而“A”/“B” - 将是位置为 A 和 B 的 ID。类似地,“A”/“C” = 将是位置为 A 和 C 的 ID。ID 在两个位置之间重叠。跨度>
  • 现在完全有意义 - 请参阅我的答案

标签: sql google-bigquery


【解决方案1】:

以下是 BigQuery 标准 SQL

#standardSQL
WITH self AS (
  SELECT arr[OFFSET(0)] place, COUNT(1) cnt
  FROM (
    SELECT ARRAY_AGG(place) arr, id
    FROM `project.dataset.table`
    GROUP BY id
    HAVING ARRAY_LENGTH(arr) = 1
  )
  GROUP BY place
), pairs AS (
  SELECT id, ARRAY_AGG(place) arr
  FROM `project.dataset.table` 
  GROUP BY id
), flat_matrix AS (
  SELECT place1, place2, COUNT(DISTINCT id) cnt
  FROM pairs, UNNEST(arr) place1, UNNEST(arr) place2
  WHERE place1 <> place2
  GROUP BY 1, 2
  UNION ALL
  SELECT place, place, cnt
  FROM self
)
SELECT place1 place,
  MAX(IF(place2 = 'A', cnt, 0)) AS A,
  MAX(IF(place2 = 'B', cnt, 0)) AS B,
  MAX(IF(place2 = 'C', cnt, 0)) AS C,
  MAX(IF(place2 = 'D', cnt, 0)) AS D 
FROM flat_matrix    

您可以使用您问题中的虚拟数据进行测试,如下所示

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 id, 'A' place UNION ALL
  SELECT 2, 'B' UNION ALL
  SELECT 1, 'C' UNION ALL
  SELECT 6, 'B' UNION ALL
  SELECT 4, 'D' UNION ALL
  SELECT 5, 'A' UNION ALL
  SELECT 6, 'C' UNION ALL
  SELECT 7, 'A' UNION ALL
  SELECT 8, 'A' UNION ALL
  SELECT 8, 'C'   
), self AS (
  SELECT arr[OFFSET(0)] place, COUNT(1) cnt
  FROM (
    SELECT ARRAY_AGG(place) arr, id
    FROM `project.dataset.table`
    GROUP BY id
    HAVING ARRAY_LENGTH(arr) = 1
  )
  GROUP BY place
), pairs AS (
  SELECT id, ARRAY_AGG(place) arr
  FROM `project.dataset.table` 
  GROUP BY id
), flat_matrix AS (
  SELECT place1, place2, COUNT(DISTINCT id) cnt
  FROM pairs, UNNEST(arr) place1, UNNEST(arr) place2
  WHERE place1 <> place2
  GROUP BY 1, 2
  UNION ALL
  SELECT place, place, cnt
  FROM self
)
SELECT place1 place,
  MAX(IF(place2 = 'A', cnt, 0)) AS A,
  MAX(IF(place2 = 'B', cnt, 0)) AS B,
  MAX(IF(place2 = 'C', cnt, 0)) AS C,
  MAX(IF(place2 = 'D', cnt, 0)) AS D 
FROM flat_matrix
GROUP BY place1
-- ORDER BY place

结果为

Row place   A   B   C   D    
1   A       2   0   2   0    
2   B       0   1   1   0    
3   C       2   1   0   0    
4   D       0   0   0   1    

【讨论】:

  • 谢谢@Mikhail。这真的很有帮助。
【解决方案2】:

我想你基本上想要:

with t as (
      select t.*, row_number() over (order by id) as seqnum
      from t
     )
select t.place,
       max(case when t2.place = 'A' then 1 else 0 end) as A,
       max(case when t2.place = 'B' then 1 else 0 end) as B,
       max(case when t2.place = 'C' then 1 else 0 end) as C,
       max(case when t2.place = 'D' then 1 else 0 end) as D
from t join
     t t2
     on t.id = t2.id and t.seqnum <> t2.seqnum
group by t.place
order by t.place;

这不完全是您在问题中的输出,但它似乎在逻辑上处理了重叠。我看不出你是如何将“A”/“A”与 1 联系起来,而将“C”/“C”与 0 联系起来的。

【讨论】:

  • 感谢您的回复。我会试试。 “A”/“A”为零,因为只有一个 ID 对 A 是唯一的,即 ID = 5,另一个 ID 与 C 共享。此外,“C”/“C”为零,因为没有唯一对 C 唯一的 ID ,它与 A 和 B 共享。
猜你喜欢
  • 2017-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-21
  • 2019-04-11
  • 2022-01-19
  • 2019-12-19
相关资源
最近更新 更多