【问题标题】:recursive CTE to combine values递归 CTE 组合值
【发布时间】:2018-02-24 02:52:23
【问题描述】:

请注意,这不是与 cmets 中引用的问题的重复,因为这需要 CTE。

如何创建一个递归的公用表表达式来组合分组数据(如string_agg()group_concat())?

例如,我有一个简单的数据集,如下所示:

┌──────┬──────────┐
│ code │ category │
╞══════╪══════════╡
│ 1    │ A        │
├──────┼──────────┤
│ 1    │ B        │
├──────┼──────────┤
│ 2    │ A        │
├──────┼──────────┤
│ 3    │ B        │
├──────┼──────────┤
│ 4    │ B        │
├──────┼──────────┤
│ 4    │ C        │
├──────┼──────────┤
│ 4    │ D        │
├──────┼──────────┤
│ 5    │ B        │
└──────┴──────────┘

我想生成一个按组组合类别的结果集,如下所示:

┌──────┬──────────┐
│ code │ category │
╞══════╪══════════╡
│ 1    │ A,B      │
├──────┼──────────┤
│ 2    │ A        │
├──────┼──────────┤
│ 3    │ B        │
├──────┼──────────┤
│ 4    │ B,C,D    │
├──────┼──────────┤
│ 5    │ B        │
└──────┴──────────┘

我认为答案可能是通用的,但我特别有兴趣为 PostgreSQL、SQLite 和 SQL Server 找到解决方案。

【问题讨论】:

  • 答案肯定不是通用或 ANSI 标准,您不需要递归 CTE 来回答这个问题。使用您实际使用的数据库进行标记。
  • 基于样本和结果,它看起来像连续行值...PostgresqlSQLiteSQL Server
  • @Anagha 不,它不是重复的。我正在寻找使用 CTE 的解决方案。其他答案没有。

标签: sql sql-server sqlite common-table-expression recursive-query


【解决方案1】:

足够的推力,猪飞得很好。但是,这不一定是个好主意。
RFC 1925

首先,获取所有不同的code 值。 然后确定每个code 的第一个(最小)category 值。 然后,在递归中,为每个code 获取下一个更大的category 值。 结果包含为每个code 执行了最新步骤的所有行:

WITH RECURSIVE OinkOink(code, category, combined, step) AS (
  SELECT code,
         (SELECT MIN(MyTable.category)
          FROM MyTable
          WHERE MyTable.code = DistinctCodes.code),
         (SELECT MIN(MyTable.category)
          FROM MyTable
          WHERE MyTable.code = DistinctCodes.code),
         1
  FROM (SELECT DISTINCT code
        FROM MyTable) AS DistinctCodes

  UNION ALL

  SELECT code,
         (SELECT MIN(MyTable.category)
          FROM MyTable
          WHERE MyTable.code     = OinkOink.code
            AND MyTable.category > OinkOink.category),
         combined || ',' ||
           (SELECT MIN(MyTable.category)
            FROM MyTable
            WHERE MyTable.code     = OinkOink.code
              AND MyTable.category > OinkOink.category),
         step + 1
  FROM OinkOink
  WHERE EXISTS (SELECT *
                FROM MyTable
                WHERE MyTable.code     = OinkOink.code
                  AND MyTable.category > OinkOink.category)
)
SELECT code, combined
FROM OinkOink
JOIN (SELECT code,
             MAX(step) AS step
      FROM OinkOink
      GROUP BY code) AS LargestSteps
USING (code, step)
ORDER BY code;

【讨论】:

    猜你喜欢
    • 2014-03-01
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多