我有两张桌子
如何在 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
===========================
我的组合成为Id 10,
MyNumberRange(10)=> 8-75-500
组合范围变为:
ValidateRange(1)=> 0-50-5至10-100-999
ValidateRange(2)=> 100-300-400至200-999-999
SO MyNumberRange(8-75-500)属于ValidateRange(0-50-5至10-100-999)
因此10是有效的
我的组合成为Id 20,
MyNumberRange(20)=> 1-400-500
组合范围变为:
ValidateRange(1)=> 0-50-5至10-100-999
ValidateRange(2)=> 100-300-400至200-999-999
SO 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
答案 0 :(得分: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;
答案 1 :(得分: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 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;