我有以下表结构,它是根据UI中的选择生成的,并且它是从UI生成的。这基本上是商店查询序列。
e.g
((条件和条件)或(条件))
Id ConditionType Value Brackets 1 NULL NULL ( 2 NULL NULL ( 3 NULL Condition NULL 4 AND NULL NULL 5 NULL Condition NULL 6 NULL NULL ) 7 OR NULL NULL 8 NULL NULL ( 9 NULL Condition NULL 10 NULL NULL ) 11 NULL NULL )
根据以上信息,我需要生成一个索引:
Id StartIndex EndIndex 1 1 11 2 2 6 3 8 10
请建议如何轻松完成。
答案 0 :(得分:1)
编辑:在第一个版本中,我错过了考虑嵌套级别。我测试了这个:)
我在DB2上工作,所以如果它不支持LATERAL连接,你可能不得不为sql-server重构这个,但是这个在DB2上用你的一组值产生了正确的结果:
with CTE_ONLY_BRACKETS as (
select *
from MYLIST
where Brackets in('(',')')
) ,
CTE_NEST_INCREMENT as (
select Id
,Brackets
,case when Brackets = '(' then 1 else -1 end as NEST_INCREMENT
from CTE_ONLY_BRACKETS
) ,
CTE_NEST_LEVEL as (
select Id
,Brackets
,S.NEST_LEVEL
from CTE_NEST_INCREMENT C
cross join lateral (
select sum( NEST_INCREMENT ) as NEST_LEVEL
from CTE_NEST_INCREMENT S
where S.Id <= C.Id
) as S
)
select row_number() over() as Id
,L.Id as StartIndex
,R.Id as EndIndex
from CTE_NEST_LEVEL R
cross join lateral (
select L.Id
from CTE_NEST_LEVEL L
where L.Brackets = '('
and L.Id < R.Id
and L.NEST_LEVEL = R.NEST_LEVEL + 1
order by L.Id desc
fetch first row only
) as L
where R.Brackets = ')'
order by L.Id
答案 1 :(得分:0)
您可以尝试一下。
DECLARE @SampleDate TABLE (Id INT, ConditionType VARCHAR(10), Value VARCHAR(10), Brackets VARCHAR(10))
INSERT INTO @SampleDate VALUES
( 1, NULL , NULL , '('),
( 2, NULL , NULL , '('),
( 3, NULL , 'Condition' , NULL),
( 4, 'AND', NULL , NULL),
( 5, NULL , 'Condition' , NULL),
( 6, NULL , NULL , ')'),
( 7, 'OR' , NULL , NULL),
( 8, NULL , NULL , '('),
( 9, NULL , 'Condition' , NULL),
( 10, NULL , NULL , ')'),
( 11, NULL , NULL , ')')
;WITH CTE AS (
SELECT * FROM @SampleDate T1
OUTER APPLY ( SELECT SUM (CASE
WHEN Brackets = '(' THEN 1 WHEN Brackets = ')' THEN -1 ELSE 0 END) Inx
FROM @SampleDate T2
WHERE T1.Id >= T2.Id ) X
)
SELECT
ROW_NUMBER() OVER(ORDER BY X1.Id) AS Id,
X1.Id StartIndex,
T.Id EndIndex
FROM CTE X1
OUTER APPLY (SELECT TOP 1 * FROM CTE X2
WHERE X2.Brackets =')' AND X2.Id > X1.Id AND X2.Inx = X1.Inx - 1 ORDER BY X2.Id ) AS T
WHERE
X1.Brackets ='('
结果:
Id StartIndex EndIndex
-------------------- ----------- -----------
1 1 11
2 2 6
3 8 10