从sql中的表读取值

时间:2014-11-15 05:37:47

标签: sql sql-server sql-server-2008

我有以下表结构,它是根据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 

请建议如何轻松完成。

2 个答案:

答案 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