【问题标题】:Recursive CTE to uniquely number groups in data set递归 CTE 到数据集中的唯一编号组
【发布时间】:2018-04-12 08:18:20
【问题描述】:

我的数据集如下:

Product_1   Product_2
   A           B
   A           A
   A           C
   C           D
   B           C
   E           E
   Z           Z

表中说的是,产品 A 实际上是产品 B,那么产品 A 当然是产品 A,产品 A 也与产品 C 相同,但考虑到产品 C 是产品 D,最终产品 A 也是与产品 D 相同。

我需要在此表中添加一列,将所有相同的产品分组如下:

Product_1   Product_2  Group
   A           B         1
   A           A         1
   A           C         1
   C           D         1
   B           C         1
   E           E         2
   Z           Z         3

我正在使用 R,因此我正在考虑将递归 CTE 与 sqldf 包一起使用。 这是大数据,所以使用矩阵来解决问题会让我超过 1.3 TB,而我没有。 有人知道怎么做吗?

【问题讨论】:

标签: sql r sqlite recursion sqldf


【解决方案1】:

此关系为commutative,因此b 计算两个方向的关系以简化以下查询。

closure 是递归 CTE,并计算 transitive closure,即等效产品的所有可能组合。

ec 计算equivalence classes,即对于每个产品,它计算同一类中最小的产品名称,例如:

一个|一个 乙|甲 C|A D|A 电子|电子 Z|Z

g 通过计算有多少较小的不同 class 值来计算组数:

一个|1 乙|1 C|1 D|1 E|2 Z|3
WITH RECURSIVE b AS (
  SELECT product_1, product_2 FROM MyTable
  UNION ALL
  SELECT product_2, product_1 FROM MyTable
),
closure AS (
  SELECT product_1, product_2 FROM b

  UNION

  SELECT c.product_1, b.product_2
  FROM closure AS c
  JOIN b ON c.product_2 = b.product_1
),
ec(product, class) AS (
  SELECT product_1, MIN(product_2)
  FROM closure
  GROUP BY product_1
),
g(product, g) AS (
  SELECT product,
         (SELECT COUNT(DISTINCT class)
          FROM ec AS ec2
          WHERE ec2.class <= ec.class)
  FROM ec
)
UPDATE MyTable
SET "Group" = (SELECT g
               FROM g
               WHERE product = MyTable.Product_1);

大数据

那么希望你有一个大磁盘来存放临时数据……

【讨论】:

  • 即使尝试使用上述数据运行此代码,我也没有得到原始数据集的更新:0 列和 0 行的数据框。警告消息:在 rsqlite_fetch(res@ptr, n = n) 中:不需要为语句调用 dbFetch(),仅用于查询
  • 该警告是由最新版本的 RSQLite 引起的,可以忽略。您可以通过降级到旧版本的 RSQLite 来避免它。
猜你喜欢
  • 1970-01-01
  • 2012-05-10
  • 2018-02-24
  • 1970-01-01
  • 2017-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多