zoukankan      html  css  js  c++  java
  • 递归实现集合求解

    数据库环境:SQL SERVER 2005

      在群里看到一道题,截图如下:

      可能有些朋友还看不懂题目的意思,我们现在就来分析一下。假设有3种产品A、产品B、产品C,产品A和产品B存在替换关系

    如果产品A和产品B中任何一种产品和产品C存在替换关系,则它们就是一组。

      实现思路:把存在替换关系的任意2种产品放到集合1中,然后遍历后续产品,如果满足关系的则加入集合1,否则,新建集合2,

    遍历符合集合2的产品并加入。

    /*测试数据*/
    WITH    tab
              AS ( SELECT   1 id ,
                            '121500125' fru ,
                            '121500132' sub_fru
                   UNION ALL
                   SELECT   2 id ,
                            '121500125' fru ,
                            '5B19A4567R' sub_fru
                   UNION ALL
                   SELECT   3 id ,
                            '121500132' fru ,
                            '121500125' sub_fru
                   UNION ALL
                   SELECT   4 id ,
                            '121500132' fru ,
                            '5B19A4567R' sub_fru
                   UNION ALL
                   SELECT   5 id ,
                            '121500178' fru ,
                            '121500180' sub_fru
                   UNION ALL
                   SELECT   6 id ,
                            '121500180' fru ,
                            '121500178' sub_fru
                   UNION ALL
                   SELECT   7 id ,
                            '121500180' fru ,
                            'SB19A46291' sub_fru
                 ),/*递归,遍历数据加入关系集合*/
            t ( id, fru, sub_fru, fru_r, gp )
              AS ( SELECT   id ,
                            fru ,
                            sub_fru ,
                            CONVERT(VARCHAR(100), fru + ',' + sub_fru) AS fru_r ,--关系集合
                            1 AS gp--组号
                   FROM     tab
                   WHERE    id = 1
                   UNION ALL
                   SELECT   t1.id ,
                            t1.fru ,
                            t1.sub_fru ,
                            CONVERT(VARCHAR(100), CASE WHEN ( CHARINDEX(t1.fru,
                                                                  t2.fru_r) > 0
                                                              OR CHARINDEX(t1.sub_fru,
                                                                  t2.fru_r) > 0
                                                            )--如果新产品和关系中的产品有关系,则加入
                                                       THEN CASE WHEN CHARINDEX(t1.fru,
                                                                  t2.fru_r) = 0
                                                                 THEN t2.fru_r
                                                                  + ',' + t1.fru
                                                                 WHEN CHARINDEX(t1.sub_fru,
                                                                  t2.fru_r) = 0
                                                                 THEN t2.fru_r
                                                                  + ','
                                                                  + t1.sub_fru
                                                                 ELSE t2.fru_r
                                                            END
                                                       ELSE t1.fru + ','
                                                            + t1.sub_fru--新建另一组的关系集合
                                                  END) AS fru_r ,
                            CASE WHEN ( CHARINDEX(t1.fru, t2.fru_r) > 0
                                        OR CHARINDEX(t1.sub_fru, t2.fru_r) > 0
                                      ) THEN t2.gp
                                 ELSE t2.gp + 1
                            END AS gp
                   FROM     tab t1 ,
                            t t2
                   WHERE    t1.id = t2.id + 1
                 ),/*取出每组集合中的最大子集*/
            t1
              AS ( SELECT   gp AS id ,
                            MAX(fru_r) AS fru
                   FROM     t
                   GROUP BY gp
                 )/*按逗号分割关系产品*/
        SELECT  t1.id ,
                col = CAST(SUBSTRING(fru, number,
                                     CHARINDEX(',', fru + ',', number) - number) AS VARCHAR(100))
        FROM    t1
                CROSS APPLY master..spt_values
        WHERE   type = 'P'
                AND number >= 1
                AND number <= LEN(fru + 'a')
                AND CHARINDEX(',', ',' + fru, number) = number
    View Code

      当然,也可以在递归的时候就把每组的产品都罗列出来,就省去后面拆分字符串的步骤。不过,这样实现也比较麻烦。

      结果如下图:

  • 相关阅读:
    sed命令详解 皇星客栈
    FD_set FD_zero 皇星客栈
    linux tr命令详解 皇星客栈
    解决中文乱码问题(Ubuntu) 皇星客栈
    FIFO深度 皇星客栈
    输入阻抗 皇星客栈
    APROM Data Flash LDROM 皇星客栈
    kubernetes 1.21 部署业务
    kubernetes 1.21部署 cephcsi rbd
    kubernetes 1.21 部署 dashboard
  • 原文地址:https://www.cnblogs.com/boss-he/p/4799076.html
Copyright © 2011-2022 走看看