在Mysql数据库中查找范围内的未分配范围
我想从指定的范围中获取未分配的范围,例如id为43的记录是父记录,我想获取未分配的记录,如下图所示,id为44和45的记录是id为43的记录的子记录在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
我假设分配的范围不重叠 它基本上由四个查询组成 第一个查询查找父项指定的起始编号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该脚本可以工作,但可能会在一些方面得到简化,从而使其更易于阅读,更高效。可能值得添加代码作为帖子,以获取一些意见。但就目前而言,它完成了所需的工作。很高兴它有用。