Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Mysql数据库中查找范围内的未分配范围_Mysql_Sql_Range - Fatal编程技术网

在Mysql数据库中查找范围内的未分配范围

在Mysql数据库中查找范围内的未分配范围,mysql,sql,range,Mysql,Sql,Range,我想从指定的范围中获取未分配的范围,例如id为43的记录是父记录,我想获取未分配的记录,如下图所示,id为44和45的记录是id为43的记录的子记录 我假设分配的范围不重叠 它基本上由四个查询组成 第一个查询查找父项指定的起始编号Batch\u number\u from与按批次编号\u from排序的第一个子记录的起始编号Batch\u number\u from之间的任何未分配编号范围。 第二个查询查找父项的子记录之间的任何未分配数字范围。 第三个查询查找父记录指定的结束编号Batch\u

我想从指定的范围中获取未分配的范围,例如id为43的记录是父记录,我想获取未分配的记录,如下图所示,id为44和45的记录是id为43的记录的子记录


我假设分配的范围不重叠

它基本上由四个查询组成

第一个查询查找父项指定的起始编号Batch\u number\u from与按批次编号\u from排序的第一个子记录的起始编号Batch\u number\u from之间的任何未分配编号范围。 第二个查询查找父项的子记录之间的任何未分配数字范围。 第三个查询查找父记录指定的结束编号Batch\u number\u to和按批次编号\u from排序的最后一个子记录的结束编号Batch\u number\u to之间的任何未分配编号范围。 最后,第四个查找没有相应子记录的父记录,因此没有分配的编号。 所有四个查询都使用UNION组合在一起

在前三个查询中,有两个子查询是重复的,因此可以移动到临时表中。它们被标记为ChildRnk和NextStart

ChildRnk按照批次号对从中排序的所有子记录进行排序

如果特定父记录中列出了另一个子项,则NextStart返回任何给定子项的下一批已分配编号batch_number_的起始编号

希望这有帮助

对于MSSQL:

SELECT 
    ChildRnk.Parent,
    Batch_Number_From AS START,
    (START-1) AS [End]
FROM 
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS 'End',
        RANK() OVER 
            (PARTITION BY a.parent_fk ORDER BY a.Batch_Number_From ASC) AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN 
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2 
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS 'End',
            RANK() 
                OVER (PARTITION BY b.parent_fk ORDER BY b.Batch_Number_From ASC) AS Rnk1
        FROM 
            VOUCHER_BATCH_ALLOCATION AS b
        WHERE 
            b.channel_from_fk = 2) c
    WHERE 
        Rnk1 != 1) NextStart
ON 
    ChildRnk.Parent = NextStart.Parent
    AND Rnk1 = Rnk2
LEFT JOIN 
    VOUCHER_BATCH_ALLOCATION
ON 
    VOUCHER_BATCH_ALLOCATION.Id = ChildRnk.Parent
    AND Rnk1 = 1
WHERE 
    Batch_Number_From IS NOT NULL
    AND Batch_Number_From < START

UNION

SELECT 
    ChildRnk.Parent,
    ([End]+1) AS START,
    (NextStart-1) AS [End]
FROM 
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS 'End',
        RANK() 
             OVER (PARTITION BY a.parent_fk ORDER BY a.Batch_Number_From ASC) AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN 
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2 
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS 'End',
            RANK() OVER 
                (PARTITION BY b.parent_fk ORDER BY b.Batch_Number_From ASC) AS Rnk1
        FROM 
            VOUCHER_BATCH_ALLOCATION AS b
        WHERE 
            b.channel_from_fk = 2) c
    WHERE 
        Rnk1 != 1) NextStart
ON 
    ChildRnk.Parent = NextStart.Parent
    AND Rnk1 = Rnk2
LEFT JOIN 
    VOUCHER_BATCH_ALLOCATION
ON 
    VOUCHER_BATCH_ALLOCATION.Id = ChildRnk.Parent
    AND Rnk1 = 1
WHERE 
    NextStart IS NOT NULL
    AND [End] < NextStart

UNION

SELECT 
    ChildRnk.Parent,
    ([End]+1) AS START,
    EndLimit.VeryEnd AS [End]
FROM 
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS 'End',
        RANK() OVER 
            (PARTITION BY a.parent_fk ORDER BY a.Batch_Number_From ASC) AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN 
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2 
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS 'End',
            RANK() OVER 
                (PARTITION BY b.parent_fk ORDER BY b.Batch_Number_From ASC) AS Rnk1
        FROM 
             VOUCHER_BATCH_ALLOCATION AS b
        WHERE 
            b.channel_from_fk = 2) c
    WHERE 
        Rnk1 != 1) NextStart
    ON 
        ChildRnk.Parent = NextStart.Parent
        AND Rnk1 = Rnk2
LEFT JOIN 
    (SELECT
        a.Id,
        a.Batch_Number_To AS VeryEnd,
        Rnk2
    FROM 
        VOUCHER_BATCH_ALLOCATION a
    LEFT JOIN
        (SELECT
            max(ChildRnk.Parent) AS MaxParent,
            max(ChildRnk.Rnk1) AS Rnk2
        FROM 
            (SELECT
                 a.Id AS Id,
                 a.parent_fk AS Parent,
                 a.Batch_Number_From AS START,
                 a.Batch_Number_To AS 'End',
                 RANK() OVER 
                     (PARTITION BY a.parent_fk ORDER BY a.Batch_Number_From ASC) AS Rnk1
            FROM 
                VOUCHER_BATCH_ALLOCATION AS a
            WHERE 
                a.channel_from_fk = 2) ChildRnk
        GROUP BY 
            ChildRnk.Parent) c
    ON 
        c.MaxParent = a.id
    WHERE 
        a.channel_from_fk = 1) EndLimit
ON 
    EndLimit.Id = ChildRnk.Parent
    AND EndLimit.Rnk2 = Rnk1
WHERE 
    EndLimit.VeryEnd IS NOT NULL
    AND [End] < EndLimit.VeryEnd

UNION 

SELECT
    a.id AS Parent,
    a.Batch_Number_From AS START,
    a.Batch_Number_To AS [End]
FROM
    VOUCHER_BATCH_ALLOCATION a
WHERE 
    a.Channel_From_Fk = 1
    And a.id not in 
        (SELECT 
            Parent_Fk 
        FROM 
            VOUCHER_BATCH_ALLOCATION 
        WHERE 
            Channel_From_Fk=2)
编辑:下面是为MySql重写的脚本 对于MySQL,我不得不用一个子查询替换该函数,这将获得相同的结果,因为不幸的是MySQL不支持它

SELECT
    ChildRnk.Parent,
    Batch_Number_From AS START,
    (START-1) AS TheEnd
FROM
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS TheEnd,
        Rnk.Rank AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    LEFT JOIN
        (SELECT
            g1.id,
            g1.Parent_Fk,
            COUNT(*) AS rank
        FROM
            VOUCHER_BATCH_ALLOCATION AS g1
        JOIN
            VOUCHER_BATCH_ALLOCATION AS g2
        ON
            (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
            AND g1.Parent_Fk = g2.Parent_Fk
        GROUP BY
            g1.Parent_Fk,
            g1.Batch_Number_From
        ORDER BY
            g1.Parent_Fk,
            rank) Rnk
    ON
        Rnk.id = a.Id
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS TheEnd,
            Rnk.Rank AS Rnk1
        FROM 
            VOUCHER_BATCH_ALLOCATION AS b
        LEFT JOIN
            (SELECT
                g1.id,
                g1.Parent_Fk,
                COUNT(*) AS rank
            FROM
                VOUCHER_BATCH_ALLOCATION AS g1
            JOIN
                VOUCHER_BATCH_ALLOCATION AS g2
            ON
                (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
                AND g1.Parent_Fk = g2.Parent_Fk
            GROUP BY
                g1.Parent_Fk,
                g1.Batch_Number_From
            ORDER BY
                g1.Parent_Fk,
                rank) Rnk
        ON
            Rnk.id = b.Id
        WHERE 
            b.channel_from_fk = 2) c
    WHERE Rnk1 != 1) NextStart
ON 
    ChildRnk.Parent = NextStart.Parent
    AND Rnk1 = Rnk2
LEFT JOIN 
    VOUCHER_BATCH_ALLOCATION
ON 
    VOUCHER_BATCH_ALLOCATION.Id = ChildRnk.Parent
    AND Rnk1 = 1
WHERE 
    Batch_Number_From IS NOT NULL
    AND Batch_Number_From < START

UNION

SELECT
    ChildRnk.Parent,
    (TheEnd+1) AS START,
    (NextStart-1) AS TheEnd
FROM
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS TheEnd,
        Rnk.rank AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    LEFT JOIN
        (SELECT
            g1.id,
            g1.Parent_Fk,
            COUNT(*) AS rank
        FROM
            VOUCHER_BATCH_ALLOCATION AS g1
        JOIN
            VOUCHER_BATCH_ALLOCATION AS g2
        ON
            (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
            AND g1.Parent_Fk = g2.Parent_Fk
        GROUP BY
            g1.Parent_Fk,
            g1.Batch_Number_From
        ORDER BY
            g1.Parent_Fk,
            rank) Rnk
    ON
        Rnk.id = a.Id
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS TheEnd,
            Rnk.rank AS Rnk1
        FROM 
            VOUCHER_BATCH_ALLOCATION AS b
        LEFT JOIN
            (SELECT
                g1.id,
                g1.Parent_Fk,
                COUNT(*) AS rank
            FROM
                VOUCHER_BATCH_ALLOCATION AS g1
            JOIN
                VOUCHER_BATCH_ALLOCATION AS g2
            ON
                (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
                AND g1.Parent_Fk = g2.Parent_Fk
            GROUP BY
                g1.Parent_Fk,
                g1.Batch_Number_From
            ORDER BY
                g1.Parent_Fk,
                rank) Rnk
        ON
            Rnk.id = b.Id
        WHERE 
            b.channel_from_fk = 2) c
    WHERE 
        Rnk1 != 1) NextStart
ON 
    ChildRnk.Parent = NextStart.Parent
    AND Rnk1 = Rnk2
LEFT JOIN 
    VOUCHER_BATCH_ALLOCATION
ON 
    VOUCHER_BATCH_ALLOCATION.Id = ChildRnk.Parent
    AND Rnk1 = 1
WHERE 
    NextStart IS NOT NULL
    AND TheEnd < NextStart

UNION

SELECT
    ChildRnk.Parent,
    (TheEnd+1) AS START,
    EndLimit.VeryEnd AS TheEnd
FROM
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS TheEnd,
        Rnk.Rank AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    LEFT JOIN
        (SELECT
            g1.id,
            g1.Parent_Fk,
            COUNT(*) AS rank
        FROM
            VOUCHER_BATCH_ALLOCATION AS g1
        JOIN
            VOUCHER_BATCH_ALLOCATION AS g2
        ON
            (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
            AND g1.Parent_Fk = g2.Parent_Fk
        GROUP BY
            g1.Parent_Fk,
            g1.Batch_Number_From
        ORDER BY
            g1.Parent_Fk,
            rank) Rnk
    ON
        Rnk.id = a.Id
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS TheEnd,
            Rnk.Rank AS Rnk1
        FROM 
            VOUCHER_BATCH_ALLOCATION AS b
        LEFT JOIN
            (SELECT
                g1.id,
                g1.Parent_Fk,
                COUNT(*) AS rank
            FROM
                VOUCHER_BATCH_ALLOCATION AS g1
            JOIN
               VOUCHER_BATCH_ALLOCATION AS g2
            ON
               (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
               AND g1.Parent_Fk = g2.Parent_Fk
            GROUP BY
               g1.Parent_Fk,
               g1.Batch_Number_From
            ORDER BY
               g1.Parent_Fk,
               rank) Rnk
        ON
            Rnk.id = b.Id
        WHERE 
            b.channel_from_fk = 2) c
    WHERE 
        Rnk1 != 1) NextStart
ON 
    ChildRnk.Parent = NextStart.Parent
    AND Rnk1 = Rnk2
LEFT JOIN
    (SELECT
        a.Id,
        a.Batch_Number_To AS VeryEnd,
        Rnk2
    FROM 
        VOUCHER_BATCH_ALLOCATION a
    LEFT JOIN
        (SELECT
            max(ChildRnk.Parent) AS MaxParent,
            max(ChildRnk.Rnk1) AS Rnk2
        FROM
            (SELECT
                a.Id AS Id,
                a.parent_fk AS Parent,
                a.Batch_Number_From AS START,
                a.Batch_Number_To AS TheEnd,
                Rnk.Rank AS Rnk1
            FROM 
                VOUCHER_BATCH_ALLOCATION AS a
            LEFT JOIN
                (SELECT
                    g1.id,
                    g1.Parent_Fk,
                    COUNT(*) AS rank
                FROM
                    VOUCHER_BATCH_ALLOCATION AS g1
                JOIN
                    VOUCHER_BATCH_ALLOCATION AS g2
                ON
                    (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
                    AND g1.Parent_Fk = g2.Parent_Fk
                GROUP BY
                    g1.Parent_Fk,
                    g1.Batch_Number_From
                ORDER BY
                    g1.Parent_Fk,
                    rank) Rnk
            ON
                Rnk.id = a.Id
            WHERE 
                a.channel_from_fk = 2) ChildRnk
        GROUP BY 
            ChildRnk.Parent) c
    ON 
        c.MaxParent = a.id
    WHERE 
        a.channel_from_fk = 1) EndLimit
ON 
    EndLimit.Id = ChildRnk.Parent
    AND EndLimit.Rnk2 = Rnk1
WHERE 
    EndLimit.VeryEnd IS NOT NULL
    AND TheEnd < EndLimit.VeryEnd

UNION

SELECT
    a.id AS Parent,
    a.Batch_Number_From AS START,
    a.Batch_Number_To AS TheEnd
FROM
    VOUCHER_BATCH_ALLOCATION a
WHERE
    a.Channel_From_Fk = 1
    AND a.id NOT IN (SELECT Parent_Fk FROM VOUCHER_BATCH_ALLOCATION WHERE Channel_From_Fk=2)

希望这有帮助

我假设分配的范围不会重叠

它基本上由四个查询组成

第一个查询查找父项指定的起始编号Batch\u number\u from与按批次编号\u from排序的第一个子记录的起始编号Batch\u number\u from之间的任何未分配编号范围。 第二个查询查找父项的子记录之间的任何未分配数字范围。 第三个查询查找父记录指定的结束编号Batch\u number\u to和按批次编号\u from排序的最后一个子记录的结束编号Batch\u number\u to之间的任何未分配编号范围。 最后,第四个查找没有相应子记录的父记录,因此没有分配的编号。 所有四个查询都使用UNION组合在一起

在前三个查询中,有两个子查询是重复的,因此可以移动到临时表中。它们被标记为ChildRnk和NextStart

ChildRnk按照批次号对从中排序的所有子记录进行排序

如果特定父记录中列出了另一个子项,则NextStart返回任何给定子项的下一批已分配编号batch_number_的起始编号

希望这有帮助

对于MSSQL:

SELECT 
    ChildRnk.Parent,
    Batch_Number_From AS START,
    (START-1) AS [End]
FROM 
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS 'End',
        RANK() OVER 
            (PARTITION BY a.parent_fk ORDER BY a.Batch_Number_From ASC) AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN 
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2 
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS 'End',
            RANK() 
                OVER (PARTITION BY b.parent_fk ORDER BY b.Batch_Number_From ASC) AS Rnk1
        FROM 
            VOUCHER_BATCH_ALLOCATION AS b
        WHERE 
            b.channel_from_fk = 2) c
    WHERE 
        Rnk1 != 1) NextStart
ON 
    ChildRnk.Parent = NextStart.Parent
    AND Rnk1 = Rnk2
LEFT JOIN 
    VOUCHER_BATCH_ALLOCATION
ON 
    VOUCHER_BATCH_ALLOCATION.Id = ChildRnk.Parent
    AND Rnk1 = 1
WHERE 
    Batch_Number_From IS NOT NULL
    AND Batch_Number_From < START

UNION

SELECT 
    ChildRnk.Parent,
    ([End]+1) AS START,
    (NextStart-1) AS [End]
FROM 
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS 'End',
        RANK() 
             OVER (PARTITION BY a.parent_fk ORDER BY a.Batch_Number_From ASC) AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN 
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2 
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS 'End',
            RANK() OVER 
                (PARTITION BY b.parent_fk ORDER BY b.Batch_Number_From ASC) AS Rnk1
        FROM 
            VOUCHER_BATCH_ALLOCATION AS b
        WHERE 
            b.channel_from_fk = 2) c
    WHERE 
        Rnk1 != 1) NextStart
ON 
    ChildRnk.Parent = NextStart.Parent
    AND Rnk1 = Rnk2
LEFT JOIN 
    VOUCHER_BATCH_ALLOCATION
ON 
    VOUCHER_BATCH_ALLOCATION.Id = ChildRnk.Parent
    AND Rnk1 = 1
WHERE 
    NextStart IS NOT NULL
    AND [End] < NextStart

UNION

SELECT 
    ChildRnk.Parent,
    ([End]+1) AS START,
    EndLimit.VeryEnd AS [End]
FROM 
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS 'End',
        RANK() OVER 
            (PARTITION BY a.parent_fk ORDER BY a.Batch_Number_From ASC) AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN 
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2 
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS 'End',
            RANK() OVER 
                (PARTITION BY b.parent_fk ORDER BY b.Batch_Number_From ASC) AS Rnk1
        FROM 
             VOUCHER_BATCH_ALLOCATION AS b
        WHERE 
            b.channel_from_fk = 2) c
    WHERE 
        Rnk1 != 1) NextStart
    ON 
        ChildRnk.Parent = NextStart.Parent
        AND Rnk1 = Rnk2
LEFT JOIN 
    (SELECT
        a.Id,
        a.Batch_Number_To AS VeryEnd,
        Rnk2
    FROM 
        VOUCHER_BATCH_ALLOCATION a
    LEFT JOIN
        (SELECT
            max(ChildRnk.Parent) AS MaxParent,
            max(ChildRnk.Rnk1) AS Rnk2
        FROM 
            (SELECT
                 a.Id AS Id,
                 a.parent_fk AS Parent,
                 a.Batch_Number_From AS START,
                 a.Batch_Number_To AS 'End',
                 RANK() OVER 
                     (PARTITION BY a.parent_fk ORDER BY a.Batch_Number_From ASC) AS Rnk1
            FROM 
                VOUCHER_BATCH_ALLOCATION AS a
            WHERE 
                a.channel_from_fk = 2) ChildRnk
        GROUP BY 
            ChildRnk.Parent) c
    ON 
        c.MaxParent = a.id
    WHERE 
        a.channel_from_fk = 1) EndLimit
ON 
    EndLimit.Id = ChildRnk.Parent
    AND EndLimit.Rnk2 = Rnk1
WHERE 
    EndLimit.VeryEnd IS NOT NULL
    AND [End] < EndLimit.VeryEnd

UNION 

SELECT
    a.id AS Parent,
    a.Batch_Number_From AS START,
    a.Batch_Number_To AS [End]
FROM
    VOUCHER_BATCH_ALLOCATION a
WHERE 
    a.Channel_From_Fk = 1
    And a.id not in 
        (SELECT 
            Parent_Fk 
        FROM 
            VOUCHER_BATCH_ALLOCATION 
        WHERE 
            Channel_From_Fk=2)
编辑:下面是为MySql重写的脚本 对于MySQL,我不得不用一个子查询替换该函数,这将获得相同的结果,因为不幸的是MySQL不支持它

SELECT
    ChildRnk.Parent,
    Batch_Number_From AS START,
    (START-1) AS TheEnd
FROM
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS TheEnd,
        Rnk.Rank AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    LEFT JOIN
        (SELECT
            g1.id,
            g1.Parent_Fk,
            COUNT(*) AS rank
        FROM
            VOUCHER_BATCH_ALLOCATION AS g1
        JOIN
            VOUCHER_BATCH_ALLOCATION AS g2
        ON
            (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
            AND g1.Parent_Fk = g2.Parent_Fk
        GROUP BY
            g1.Parent_Fk,
            g1.Batch_Number_From
        ORDER BY
            g1.Parent_Fk,
            rank) Rnk
    ON
        Rnk.id = a.Id
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS TheEnd,
            Rnk.Rank AS Rnk1
        FROM 
            VOUCHER_BATCH_ALLOCATION AS b
        LEFT JOIN
            (SELECT
                g1.id,
                g1.Parent_Fk,
                COUNT(*) AS rank
            FROM
                VOUCHER_BATCH_ALLOCATION AS g1
            JOIN
                VOUCHER_BATCH_ALLOCATION AS g2
            ON
                (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
                AND g1.Parent_Fk = g2.Parent_Fk
            GROUP BY
                g1.Parent_Fk,
                g1.Batch_Number_From
            ORDER BY
                g1.Parent_Fk,
                rank) Rnk
        ON
            Rnk.id = b.Id
        WHERE 
            b.channel_from_fk = 2) c
    WHERE Rnk1 != 1) NextStart
ON 
    ChildRnk.Parent = NextStart.Parent
    AND Rnk1 = Rnk2
LEFT JOIN 
    VOUCHER_BATCH_ALLOCATION
ON 
    VOUCHER_BATCH_ALLOCATION.Id = ChildRnk.Parent
    AND Rnk1 = 1
WHERE 
    Batch_Number_From IS NOT NULL
    AND Batch_Number_From < START

UNION

SELECT
    ChildRnk.Parent,
    (TheEnd+1) AS START,
    (NextStart-1) AS TheEnd
FROM
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS TheEnd,
        Rnk.rank AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    LEFT JOIN
        (SELECT
            g1.id,
            g1.Parent_Fk,
            COUNT(*) AS rank
        FROM
            VOUCHER_BATCH_ALLOCATION AS g1
        JOIN
            VOUCHER_BATCH_ALLOCATION AS g2
        ON
            (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
            AND g1.Parent_Fk = g2.Parent_Fk
        GROUP BY
            g1.Parent_Fk,
            g1.Batch_Number_From
        ORDER BY
            g1.Parent_Fk,
            rank) Rnk
    ON
        Rnk.id = a.Id
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS TheEnd,
            Rnk.rank AS Rnk1
        FROM 
            VOUCHER_BATCH_ALLOCATION AS b
        LEFT JOIN
            (SELECT
                g1.id,
                g1.Parent_Fk,
                COUNT(*) AS rank
            FROM
                VOUCHER_BATCH_ALLOCATION AS g1
            JOIN
                VOUCHER_BATCH_ALLOCATION AS g2
            ON
                (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
                AND g1.Parent_Fk = g2.Parent_Fk
            GROUP BY
                g1.Parent_Fk,
                g1.Batch_Number_From
            ORDER BY
                g1.Parent_Fk,
                rank) Rnk
        ON
            Rnk.id = b.Id
        WHERE 
            b.channel_from_fk = 2) c
    WHERE 
        Rnk1 != 1) NextStart
ON 
    ChildRnk.Parent = NextStart.Parent
    AND Rnk1 = Rnk2
LEFT JOIN 
    VOUCHER_BATCH_ALLOCATION
ON 
    VOUCHER_BATCH_ALLOCATION.Id = ChildRnk.Parent
    AND Rnk1 = 1
WHERE 
    NextStart IS NOT NULL
    AND TheEnd < NextStart

UNION

SELECT
    ChildRnk.Parent,
    (TheEnd+1) AS START,
    EndLimit.VeryEnd AS TheEnd
FROM
    (SELECT
        a.Id AS Id,
        a.parent_fk AS Parent,
        a.Batch_Number_From AS START,
        a.Batch_Number_To AS TheEnd,
        Rnk.Rank AS Rnk1
    FROM 
        VOUCHER_BATCH_ALLOCATION AS a
    LEFT JOIN
        (SELECT
            g1.id,
            g1.Parent_Fk,
            COUNT(*) AS rank
        FROM
            VOUCHER_BATCH_ALLOCATION AS g1
        JOIN
            VOUCHER_BATCH_ALLOCATION AS g2
        ON
            (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
            AND g1.Parent_Fk = g2.Parent_Fk
        GROUP BY
            g1.Parent_Fk,
            g1.Batch_Number_From
        ORDER BY
            g1.Parent_Fk,
            rank) Rnk
    ON
        Rnk.id = a.Id
    WHERE 
        a.channel_from_fk = 2) ChildRnk
LEFT JOIN
    (SELECT
        c.Parent,
        c.START AS NextStart,
        (Rnk1-1) AS Rnk2
    FROM 
        (SELECT
            b.Id AS Id,
            b.parent_fk AS Parent,
            b.Batch_Number_From AS START,
            b.Batch_Number_To AS TheEnd,
            Rnk.Rank AS Rnk1
        FROM 
            VOUCHER_BATCH_ALLOCATION AS b
        LEFT JOIN
            (SELECT
                g1.id,
                g1.Parent_Fk,
                COUNT(*) AS rank
            FROM
                VOUCHER_BATCH_ALLOCATION AS g1
            JOIN
               VOUCHER_BATCH_ALLOCATION AS g2
            ON
               (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
               AND g1.Parent_Fk = g2.Parent_Fk
            GROUP BY
               g1.Parent_Fk,
               g1.Batch_Number_From
            ORDER BY
               g1.Parent_Fk,
               rank) Rnk
        ON
            Rnk.id = b.Id
        WHERE 
            b.channel_from_fk = 2) c
    WHERE 
        Rnk1 != 1) NextStart
ON 
    ChildRnk.Parent = NextStart.Parent
    AND Rnk1 = Rnk2
LEFT JOIN
    (SELECT
        a.Id,
        a.Batch_Number_To AS VeryEnd,
        Rnk2
    FROM 
        VOUCHER_BATCH_ALLOCATION a
    LEFT JOIN
        (SELECT
            max(ChildRnk.Parent) AS MaxParent,
            max(ChildRnk.Rnk1) AS Rnk2
        FROM
            (SELECT
                a.Id AS Id,
                a.parent_fk AS Parent,
                a.Batch_Number_From AS START,
                a.Batch_Number_To AS TheEnd,
                Rnk.Rank AS Rnk1
            FROM 
                VOUCHER_BATCH_ALLOCATION AS a
            LEFT JOIN
                (SELECT
                    g1.id,
                    g1.Parent_Fk,
                    COUNT(*) AS rank
                FROM
                    VOUCHER_BATCH_ALLOCATION AS g1
                JOIN
                    VOUCHER_BATCH_ALLOCATION AS g2
                ON
                    (g2.Batch_Number_From, g2.id) <= (g1.Batch_Number_From, g1.id)
                    AND g1.Parent_Fk = g2.Parent_Fk
                GROUP BY
                    g1.Parent_Fk,
                    g1.Batch_Number_From
                ORDER BY
                    g1.Parent_Fk,
                    rank) Rnk
            ON
                Rnk.id = a.Id
            WHERE 
                a.channel_from_fk = 2) ChildRnk
        GROUP BY 
            ChildRnk.Parent) c
    ON 
        c.MaxParent = a.id
    WHERE 
        a.channel_from_fk = 1) EndLimit
ON 
    EndLimit.Id = ChildRnk.Parent
    AND EndLimit.Rnk2 = Rnk1
WHERE 
    EndLimit.VeryEnd IS NOT NULL
    AND TheEnd < EndLimit.VeryEnd

UNION

SELECT
    a.id AS Parent,
    a.Batch_Number_From AS START,
    a.Batch_Number_To AS TheEnd
FROM
    VOUCHER_BATCH_ALLOCATION a
WHERE
    a.Channel_From_Fk = 1
    AND a.id NOT IN (SELECT Parent_Fk FROM VOUCHER_BATCH_ALLOCATION WHERE Channel_From_Fk=2)

希望这对您有所帮助

另外,您可以更详细地描述一下,您说显示的表是父表。子项的结构是什么,我假设它保存分配的批次号?到目前为止,我所做的是我可以得到父项分配和分配的范围,但我还没有找到如何从这两个信息中找出未分配的范围,选择*来自凭证批次分配,其中父项FK为空,通道FK为1,ID为43;从凭证\批次\分配中选择*,其中父项\ FK不为空,父项\ FK=43;您还可以更详细地描述一下,您说显示的表是父表。子项的结构是什么,我假设它保存分配的批次号?到目前为止,我所做的是我可以得到父项分配和分配的范围,但我还没有找到如何从这两个信息中找出未分配的范围,选择*来自凭证批次分配,其中父项FK为空,通道FK为1,ID为43;从凭证\批次\分配中选择*,其中父项\ FK不为空,父项\ FK=43;我已经试过了,我给出了这个错误,你的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册,以了解在第4行“警告”-->W 1:您的SQL语法中有错误,请在“[END]附近使用正确的语法,从SELECT a.ID AS ID,a.PARENT_FK AS PARENT.”;查看与您的MySQL服务器版本对应的手册,了解在第4Hmmm行的“[END]附近使用的正确语法,选择a.ID作为ID,a.PARENT_FK作为PARENT”,是的,我知道了。我的脚本是为在MSSQL而不是MySql中使用而编写的。我会看看它是否可以修改。我已经将修改后的MySql脚本添加到ab中
我无法回答。希望它有用这个很好,我会花几个月的时间让它工作@DMK该脚本可以工作,但可能会在一些方面得到简化,从而使其更易于阅读,更高效。可能值得添加代码作为帖子,以获取一些意见。但就目前而言,它完成了所需的工作。很高兴它有用。我已经试过了,我给出了这个错误,如果您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册,以了解在第4行“警告”-->W 1:您的SQL语法中有错误,请在“[END]附近使用正确的语法,从SELECT a.ID AS ID,a.PARENT_FK AS PARENT.”;查看与您的MySQL服务器版本对应的手册,了解在第4Hmmm行的“[END]附近使用的正确语法,选择a.ID作为ID,a.PARENT_FK作为PARENT”,是的,我知道了。我的脚本是为在MSSQL而不是MySql中使用而编写的。我会看看它是否可以修改。我已经在上面的答案中添加了修改后的MySql脚本。希望它有用这个很好,我会花几个月的时间让它工作@DMK该脚本可以工作,但可能会在一些方面得到简化,从而使其更易于阅读,更高效。可能值得添加代码作为帖子,以获取一些意见。但就目前而言,它完成了所需的工作。很高兴它有用。