SQL Server 2012-CTE recursivo com duas condições sob as quais cláusula

#1 editar

Mudei a cláusula de e para onde tudo funcionava bem. Mas eu precisava usar uma junção na parte recursiva do CTE e o problema apareceu novamente, porque eu não posso usar uma junção externa aqui. Então, mudei a junção para uma aplicação exterior e funcionou bem.


SQL Fiddle: http://sqlfiddle.com/#! 18 / 9eecb/81809

Estou a tentar implementar um CTE recursivo que recebe duas idades e aumenta estas idades até que ambos sejam iguais a 120. O problema é quando tento adicionar uma cláusula onde na parte recursiva os predicados são completamente ignorados:

;with age_cte as (
    select
        26 as wife_age,
        28 as husband_age

    union all

    select
        age_cte.wife_age + 1,
        age_cte.husband_age + 1

    from age_cte

    where wife_age < 120 and husband_age < 120

) select * from age_cte;
Assim que uma das idades atingir os 120, o CTE pára. No exemplo, quando a idade do marido é igual a 120, a idade da esposa é de 118 e, em seguida, os cálculos param.

Sei que a base de dados obedece à lógica da consulta. A minha pergunta é o que devo fazer para aplicar a lógica correta a esse CTE, isto é, retornar nulo quando um a idade passa dos 120 até a outra atingir os 120?

Example:

.     .
.     .
.     .
118   120
119   NULL
120   NULL

eu tentei usar um CTE com duas âncoras e duas partes recursivas como as seguintes do exemplo de documentação ("H. usando múltiplas âncoras e membros recursivos"):

create table age (
    wife_age int,
    husband_age int
);
insert into age values(26, 28);
;with age_cte as (
    -- first anchor
    select
        wife_age
    from age
    union
    -- second anchor
    select
        husband_age
    from age

    union all

    select
        age_cte.wife_age + 1
    from age_cte

    where wife_age < 120

    union all
    --
    select
        age_cte.husband_age + 1
    from age_cte

    where husband_age < 120

) select * from age_cte;

estou a perder algo, porque me dá "nome de coluna inválido" para a "criação" na segunda consulta recursiva.

também tentei esta consulta

;with age_cte as (
    select
        26 as wife_age,
        28 as husband_age

    union all

    select
        case when age_cte.wife_age + 1 > 120 then null else age_cte.wife_age + 1 end,
        case when age_cte.husband_age + 1 > 120 then null else age_cte.husband_age + 1 end

    from age_cte

    where 120 >= case 
                     when age_cte.wife_age + 1 < age_cte.husband_age + 1 then
                         age_cte.wife_age + 1
                     else
                         age_cte.husband_age + 1
                 end


) select * from age_cte;
Mas Ou dá um loop infinito ou a idade vai para 119. a chegar aos 120.

Author: GMB, 2020-04-04

1 answers

Isto deve fazer o que quiseres.
with age_cte as (
    select 26 as wife_age, 28 as husband_age
    union all
    select
        case when wife_age < 120 then wife_age + 1 end,
        case when husband_age < 120 then husband_age + 1 end
    from age_cte
    where wife_age < 120 or husband_age < 120

) 
select * from age_cte;

Isto é:

  • Você quer or na cláusula where da consulta recursiva em vez de and, por isso a consulta continua até que ambas as idades atinjam 120

  • Você pode usar a lógica condicional em select para produzir null s quando a idade excede 120

Demonstração em DB Fiddle:

wife_age | husband_age
-------: | ----------:
      26 |          28
      27 |          29
      28 |          30
      29 |          31
...
     116 |         118
     117 |         119
     118 |         120
     119 |        null
     120 |        null
 1
Author: GMB, 2020-04-04 20:33:45