7

Ho le seguenti tabelle:uso ricorsive tavolo comune espressioni per trovare no.s consecutivi da due tabelle

Actual   Optional 
------   -------- 
4     3 
13    6 
20    7 
26    14 
        19 
        21 
        27 
        28 

quello che devo fare è selezionare:

1) tutti i valori Tabella "reale".

2) selezionare i valori da tabella "opzionali" se formano una serie consecutiva con la tabella "reale" valori

Il risultato atteso è:

Answer 
------ 
4 
13 
20 
26 
3 --because it is consecutive to 4 (i.e 3=4-1) 
14 --14=13+1 
19 --19=20-1 
21 --21=20+1 
27 --27=26+1 
28 --this is the important case.28 is not consecutive to 26 but 27 
    --is consecutive to 26 and 26,27,28 together form a series. 

Ho scritto una query utilizzando ricorsiva cte ma è in loop per sempre e fallisce dopo che la ricorsione raggiunge 100 livelli. Il problema che ho affrontato è di 27 partite con 26, 28 partite con 27 e 27 con 28.again 28 con 27 ... (per sempre)

Ecco la domanda che ho scritto:

with recurcte as 
     (
     select num as one,num as two from actual 
     union all 
     select opt.num as one,cte.two as two 
     from recurcte cte join optional opt 
     on opt.num+1=cte.one or opt.num-1=cte.one 
     )select * from recurcte 
+2

È questo compito? Perché la stipula CTE? –

+0

questo non è compito. Questa è una piccola parte di un grosso problema che ho.Io ho scritto la query per la maggior parte. Il problema deve essere scritto in una singola query. Questo è il motivo per cui una clausola di cte – psy

+0

Quindi è possibile rimuovere questa clausola sulle CTE recursive, quindi? –

risposta

6
;WITH Combined 
    AS (SELECT 1 AS Actual, N 
     FROM (VALUES(4), 
         (13), 
         (20), 
         (26)) Actual(N) 
     UNION ALL 
     SELECT 0 AS Actual, N 
     FROM (VALUES(3), 
         (6), 
         (7), 
         (14), 
         (19), 
         (21), 
         (27), 
         (28)) Optional (N)), 
    T1 
    AS (SELECT *, 
       N - DENSE_RANK() OVER (ORDER BY N) AS Grp 
     FROM Combined), 
    T2 
    AS (SELECT *, 
       MAX(Actual) OVER (PARTITION BY Grp) AS HasActual 
     FROM T1) 
SELECT DISTINCT N 
FROM T2 
WHERE HasActual = 1 
+1

Won ' t lavorare senza punto e virgola prima di WITH;) – sll

+3

@sil non necessariamente vero se si terminano tutte le istruzioni correttamente (come si dovrebbe). Bloggato su questo due anni fa: http://sqlblog.com/blogs/aaron_bertrand/archive/2009/09/03/ladies-and-gentlemen-start-your-semi-colons.aspx –

+2

E a meno che non sia la prima affermazione in un lotto. Che, come mostrato, lo è. – MatBailie

1

Questo CTE ti fornirà i dati che stai cercando. La ricorsione non è necessaria per questo.

declare @Actual table (i int) 
declare @Optional table (i int) 

insert into @Actual 
    select 4 union select 13 union select 20 union select 26 

insert into @Optional 
    select 3 union select 6 union select 7 union select 14 union select 19 
    union select 21 union select 27 union select 28 

;with rownum as (
    select *, ROW_NUMBER() OVER (ORDER BY i) as 'RN' 
    from (
     select 
      i, 'A' as 'Source' 
     from 
      @Actual 
     union 
     select 
      i, 'O' 
     from 
      @Optional 
    ) a 
) 

select distinct 
    d.i 
from 
    rownum a 
    inner join rownum d 
     on a.i - d.i = a.rn - d.rn 
where 
    a.source = 'A' 
+0

Wow, bella tecnica! – AakashM

+0

Grazie mille :) –

+0

vale la pena notare che questo approccio verrà confuso se ci sono valori duplicati, sia in una tabella che nella loro unione – AakashM

Problemi correlati