合并组(如果它们包含相同的值)

enyaitl3  于 2021-08-04  发布在  Java
关注(0)|答案(1)|浏览(378)

我有下表:

+-----+----+---------+
| grp | id | sub_grp |
+-----+----+---------+
|  10 | A2 |       1 |
|  10 | B4 |       2 |
|  10 | F1 |       2 |
|  10 | B3 |       3 |
|  10 | C2 |       4 |
|  10 | A2 |       4 |
|  10 | H4 |       5 |
|  10 | K0 |       5 |
|  10 | Z3 |       5 |
|  10 | F1 |       5 |
|  10 | A1 |       5 |
|  10 | A  |       6 |
|  10 | B  |       6 |
|  10 | B  |       7 |
|  10 | C  |       7 |
|  10 | C  |       8 |
|  10 | D  |       8 |
|  20 | A  |       1 |
|  20 | B  |       1 |
|  20 | B  |       2 |
|  20 | C  |       2 |
|  20 | C  |       3 |
|  20 | D  |       3 |
+-----+----+---------+

在每个 grp ,我的目标是合并所有 sub_grp 至少共享一个 id .
超过2个 sub_grp 可以合并在一起。
预期结果应为:

+-----+----+---------+
| grp | id | sub_grp |
+-----+----+---------+
|  10 | A2 |       1 |
|  10 | B4 |       2 |
|  10 | F1 |       2 |
|  10 | B3 |       3 |
|  10 | C2 |       1 |
|  10 | A2 |       1 |
|  10 | H4 |       2 |
|  10 | K0 |       2 |
|  10 | Z3 |       2 |
|  10 | F1 |       2 |
|  10 | A1 |       2 |
|  10 | A  |       6 |
|  10 | B  |       6 |
|  10 | B  |       6 |
|  10 | C  |       6 |
|  10 | C  |       6 |
|  10 | D  |       6 |
|  20 | A  |       1 |
|  20 | B  |       1 |
|  20 | B  |       1 |
|  20 | C  |       1 |
|  20 | C  |       1 |
|  20 | D  |       1 |
+-----+----+---------+

下面是一个sql摆弄测试值:http://sqlfiddle.com/#!9/13666c/2号
我试图用存储过程或查询来解决这个问题。
这是我上一个问题的改进:合并包含相同值的行

jaql4c8m

jaql4c8m1#

我对这个问题的理解

如果一个子组中的任何一个id与另一个子组中的任何一个id匹配,则合并子组。给定的sub\u grp只能与另一个子\u grp(升序中最早的)合并。

免责声明

此代码可能有效。没有测试,因为op没有提供DDL和数据脚本。

解决方案

UPDATE final
SET sub_grp = new_sub_grp
FROM
    -- For each grp, sub_grp combination return a matching new_sub_grp
    ( SELECT a.grp, a.sub_grp, MatchGrp.sub_grp AS new_sub_grp
    FROM tbl AS a
        -- Inner join will exclude cases where there are no matching sub_grp and thus nothing to update.
        INNER JOIN
            -- Find the earliest (if more than one sub-group is a match) matching sub-group where one of the IDs matches
            ( SELECT TOP 1 grp, sub_grp
            FROM tbl AS b
            -- b.sub_grp > a.sub_grp - this will only look at the earlier sub-groups avoiding the "double linking"
            WHERE b.grp = a.grp AND b.sub_grp > a.sub_grp AND b.ID = a.ID 
            ORDER BY grp, sub_grp ) AS MatchGrp ON 1 = 1
    -- Only return one record per grp, sub_grp combo
    GROUP BY grp, sub_grp, MatchGrp.sub_grp ) AS final

您可以在下面的帮助下,将子组重新编号为一个单独的update语句 DENSE_RANK 窗口功能。

相关问题