如何识别有效/无效数字组合,而每个组合被拆分为多行
Posted
技术标签:
【中文标题】如何识别有效/无效数字组合,而每个组合被拆分为多行【英文标题】:How To Identify Valid/Invalid Number Combination Whereas Each Combination Is Splitted Into Multi Rows 【发布时间】:2017-05-23 07:59:16 【问题描述】:我有两张桌子
-
有效组合范围(ValidationTable)
我的验证组合。 (MyListTable)
如何识别MyListTable中的VALID或INVALID组合?而每个组合都通过 Id 和 Type-Id 分成多行
如下例所示,ValidationTable 中有两个组合,MYListTable 中有两个组合进行验证。
示例表和预期结果:
=====================
** ValidationTable **
===========================================================
| ValidRangeId | TypeId | ValidNumberFrom | ValidNumberTo |
===========================================================
| 1 | 1 | 0 | 10 |
| 1 | 2 | 50 | 100 |
| 1 | 3 | 5 | 999 |
| 2 | 1 | 100 | 200 |
| 2 | 2 | 300 | 999 |
| 2 | 3 | 400 | 999 |
===========================================================
====================
** MyListTable **
===========================================
| MyRangeId | TypeId | MyNumber |
===========================================
| 10 | 1 | 8 |
| 10 | 2 | 75 |
| 10 | 3 | 500 |
| 20 | 1 | 1 |
| 20 | 2 | 400 |
| 20 | 3 | 500 |
===========================================
====================
** EXPACTED RESULT **
===========================
| MyRangeId | Result |
===========================
| 10 | Valid | Combination numbers are in valid range
| 20 | Invalid | Combination numbers are NOT in valid range
===========================
10 如何在 MyListTable 中有效!!!
我的组合变成了 Id 10,
MyNumberRange(10) => 8-75-500
而组合范围变成:
ValidateRange(1) => 0-50-5 到 10-100-999
ValidateRange(2) => 100-300-400 到 200-999-999
所以 MyNumberRange (8-75-500) 属于 ValidateRange(0-50-5 到 10-100-999)
因此 10 是有效的
如何 20 在 MyListTable 中无效!!!
我的组合变成了 ID 20,
MyNumberRange(20) => 1-400-500
而组合范围变成:
ValidateRange(1) => 0-50-5 到 10-100-999
ValidateRange(2) => 100-300-400 到 200-999-999
所以 MyNumberRange (1-400-500) 不属于 ValidateRange(0-50-5 到 10-100-999 也不是 100-300-400 到 200-999-999)
因此 20 无效
这里是上面表格的 SQL:(结果固定在这个 SQL 中只是为了解释)
IF OBJECT_ID('tempdb.dbo.#ValidationTable', 'U') IS NOT NULL DROP TABLE #ValidationTable;
IF OBJECT_ID('tempdb.dbo.#MyListTable', 'U') IS NOT NULL DROP TABLE #MyListTable;
IF OBJECT_ID('tempdb.dbo.#Result', 'U') IS NOT NULL DROP TABLE #Result;
SELECT * INTO #ValidationTable
FROM (SELECT 1 ValidRangeId, 1 TypeId, 0 ValidNumberFrom, 10 ValidNumberTo UNION
SELECT 1 ValidRangeId, 2 TypeId, 50 ValidNumberFrom, 100 ValidNumberTo UNION
SELECT 1 ValidRangeId, 3 TypeId, 5 ValidNumberFrom, 999 ValidNumberTo UNION
SELECT 2 ValidRangeId, 1 TypeId, 100 ValidNumberFrom, 200 ValidNumberTo UNION
SELECT 2 ValidRangeId, 2 TypeId, 300 ValidNumberFrom, 999 ValidNumberTo UNION
SELECT 2 ValidRangeId, 3 TypeId, 400 ValidNumberFrom, 999 ValidNumberTo) v
SELECT * INTO #MyListTable
FROM (SELECT 10 MyRangeId, 1 TypeId, 8 MyNumber UNION
SELECT 10 MyRangeId, 2 TypeId, 75 MyNumber UNION
SELECT 10 MyRangeId, 3 TypeId, 500 MyNumber UNION
SELECT 20 MyRangeId, 1 TypeId, 1 MyNumber UNION
SELECT 20 MyRangeId, 2 TypeId, 400 MyNumber UNION
SELECT 20 MyRangeId, 3 TypeId, 500 MyNumber) m
SELECT * INTO #Result
FROM (SELECT 10 MyRangeId, 'Valid' Result UNION
SELECT 20 MyRangeId, 'Invalid' Result) r
SELECT * FROM #ValidationTable
SELECT * FROM #MyListTable
SELECT * FROM #Result
【问题讨论】:
MyRangeId
是否应该与ValidRangeId
具有相同的值?请多解释一下你是如何得到这些预期结果的。解释为什么 10 有效而 20 无效。
MyRangeId 是否应该与 ValidRangeId 具有相同的值?答案是没有不同的 ID
评论时不确定是否需要大写,表示你在喊。使用 bold 来添加重点而不是大写。
我很抱歉....!!!更新的问题,我解释了请审查许多 thxxx
【参考方案1】:
请检查:
with RI as
(
select
distinct(MyRangeId) MyRangeIdDistinct
from
MyListTable
)
select
RI.MyRangeIdDistinct MyRangeId,
case
when
(
select count(distinct(VT.ValidRangeId)) from
ValidationTable VT,
MyListTable MLT
where
RI.MyRangeIdDistinct=MLT.MyRangeId and
VT.TypeId=MLT.TypeId and
MLT.MyNumber not between VT.ValidNumberFrom and ValidNumberTo
) < (select count(distinct(VT2.ValidRangeId)) from ValidationTable VT2)
then
'Valid'
else
'Invalid'
end Result
from
RI
order by 1;
【讨论】:
MyRangeId 是否应该与 ValidRangeId 具有相同的值? ****所以答案是=没有两个表都有自己的ID 那么如何识别对应的记录呢?为什么 1 属于 10 而不是 20? Ids 在两个表中都没有任何作用,只接受它的帮助来组合数字,需要更多关于你的 Q 的细节“为什么 1 属于 10 而不是 20?”谢谢 在我看来,您正在根据 ValidRangeId=1 的有效记录范围验证 MyRangeId=10 的记录。如果您要针对 (2,2,300,999) 验证记录 (10, 2, 75),那么它将失败,但您仍然希望 MyRangeId=10 为“有效”。这就是我的问题,如何找到特定的 MyListTable 记录对应的验证记录? 更新了问题以解释 10 是如何有效而 20 是无效的,请查看。许多thxx【参考方案2】:好吧,没有太多测试,可能不是最佳解决方案,但可以通过这种方式添加 First Match:
with RI as
(
select
distinct(MyRangeId) MyRangeIdDistinct
from
MyListTable
)
select
RI.MyRangeIdDistinct MyRangeId,
case
when
(
select count(distinct(VT.ValidRangeId)) from
ValidationTable VT,
MyListTable MLT
where
RI.MyRangeIdDistinct=MLT.MyRangeId and
VT.TypeId=MLT.TypeId and
MLT.MyNumber not between VT.ValidNumberFrom and VT.ValidNumberTo
) < (select count(distinct(VT2.ValidRangeId)) from ValidationTable VT2)
then
'Valid'
else
'Invalid'
end Result,
(
select Min(VT3.ValidRangeId) from
ValidationTable VT3,
MyListTable MLT3
where
(
select count(distinct(VT4.ValidRangeId)) from
ValidationTable VT4,
MyListTable MLT4
where
RI.MyRangeIdDistinct=MLT4.MyRangeId and
VT4.TypeId=MLT4.TypeId and
MLT4.MyNumber not between VT4.ValidNumberFrom and VT4.ValidNumberTo
) = (select count(distinct(VT5.ValidRangeId)) from ValidationTable VT5
where VT5.ValidRangeId=VT3.ValidRangeId)
) FirstMatch
from
RI
order by 1;
【讨论】:
它与样本一起工作,但不适用于我正在使用的实际表,在 FirstMatch 中总是返回 NULL .... 有什么遗漏或者您可以查看一下吗?谢谢以上是关于如何识别有效/无效数字组合,而每个组合被拆分为多行的主要内容,如果未能解决你的问题,请参考以下文章
在 arm neon 中有效地重新洗牌和组合 16 个 3 位数字
如何找到添加两个变量的所有可能组合,每个变量都附加到一个乘数,总和为一个给定的数字(cin)?