none
CTE query filha RRS feed

  • Pergunta

  • Tenho a seguinte tabela:

    CREATE TABLE PlanoContas (

        ID INT NOT NULL,

        IDSup INT NULL,

        Descricao VARCHAR(50))

     

     

        ALTER TABLE PlanoContas ADD CONSTRAINT PK_Plano PRIMARY KEY (ID)

     

    ALTER TABLE PlanoContas ADD CONSTRAINT FK_Plano FOREIGN KEY (IDSup)

    REFERENCES PlanoContas (ID)

     

    INSERT INTO PlanoContas VALUES (01,NULL,'Ativo')

    INSERT INTO PlanoContas VALUES (02,01,'Ativo Circulante')

    INSERT INTO PlanoContas VALUES (03,02,'Disponibilidades')

    INSERT INTO PlanoContas VALUES (04,03,'Caixa')

    INSERT INTO PlanoContas VALUES (05,04,'Caixa Geral')

    INSERT INTO PlanoContas VALUES (06,03,'Contas Bancárias')

    INSERT INTO PlanoContas VALUES (07,06,'Conta Corrente')

    INSERT INTO PlanoContas VALUES (08,06,'Conta Poupança')

     

     

    INSERT INTO PlanoContas VALUES (09,02,'Créditos')

    INSERT INTO PlanoContas VALUES (10,09,'Duplicatas')

    INSERT INTO PlanoContas VALUES (11,10,'Duplicatas Descontadas')

    INSERT INTO PlanoContas VALUES (12,10,'Duplicatas a Receber')

    INSERT INTO PlanoContas VALUES (13,06,'Conta Investimento')

     

    Abaixo tem uma CTE de exemplo que achei em um artigo, estou tentando entender como a CTE funciona recursivamente.

    ;WITH Res (ID, IDSup, Descricao) As (

        SELECT ID, IDSup, CAST(Descricao As VARCHAR(MAX)) FROM PlanoContas

        WHERE IDSup IS NULL

        UNION ALL

        SELECT F.ID, F.IDSup, P.Descricao + ' -> ' + F.Descricao

        FROM Res As P

        INNER JOIN PlanoContas As F ON P.ID = F.IDSup)

     

     SELECT ID, Descricao FROM Res

    ORDER BY ID

     

     

    select * from PlanoContas

     

    Minha pergunta é a seguinte, o que está aqui dentro? "    FROM Res As P " 

    Achei que fosse a query pai, só a primeira linha.

    Mas abaixo ele faz um join:

        INNER JOIN PlanoContas As F ON P.ID = F.IDSup)

     

    E com esse join, se fosse só a primeira linha, só ia conseguir fazer um join, 1=1.

    Não consigo entender o que tem dentro da tabela da CTE, e como a segunda query da um select dentro dela mesmo.

     

    Qualquer ajuda é útil. Valeu


    Aprendiz
    domingo, 19 de junho de 2011 21:56

Respostas

  • Edivaldo, CTE recursiva é isso: é você poder utilizar a "tabela" que está sendo criada quando ainda está dentro dela. Acho que seria bom um pouco mais de conceito, segundo o BOL:

    "Uma CTE recursiva consiste em três elementos: 

    1) Invocação da rotina.

    A primeira invocação da CTE recursiva consiste em um ou mais CTE_query_definitions associadas pelos operadores UNION ALL, UNION, EXCEPT ou INTERSECT. Como essas definições de consultas constituem o conjunto de resultados base da estrutura da CTE, são citados como membros de ancoragem.

    CTE_query_definitions são considerados membros de ancoragem, exceto se fizerem referência à própria CTE. Todas as definições de consulta de membro de ancoragem devem ser posicionadas antes que a primeira definição de membro recursivo e o operador UNION ALL precisem ser usados para unir o último membro de ancoragem ao primeiro membro recursivo.

    2) Invocação recursiva da rotina.

    A invocação recursiva inclui uma ou mais CTE_query_definitions associadas por operadores UNION ALL que fazem referência à própria CTE. Essas definições de consulta estão denominadas membros recursivos. 

    3) Verificação de término. 

    A verificação de término é implícita; a recursão pára quando nenhuma linha é retornada da invocação anterior."

    E ainda:

    "A estrutura de uma CTE recursiva deve conter no mínimo um membro de ancoragem e um membro recursivo. O pseudocódigo a seguir mostra os componentes de uma CTE recursiva simples que contém um único membro de ancoragem e um único membro recursivo. 

    WITH cte_name ( column_name [,...n] ) AS 

    (

    CTE_query_definition –- Anchor member is defined. 

    UNION ALL 

    CTE_query_definition –- Recursive member is defined referencing cte_name. 

    -- Statement using the CTE 

    SELECT * FROM cte_name"

     

    Fora isso, acredito que a leitura dos artigos do Thiago seriam de total ajuda.

    Parte 1: http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-1/

    Parte 2: http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-2-final/

    Parte 3: http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-3-o-retorno/


    Roberson Ferreira - Database Developer

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    • Sugerido como Resposta Eder Costa segunda-feira, 27 de junho de 2011 18:41
    • Marcado como Resposta Edivaldo Junior quarta-feira, 29 de junho de 2011 20:51
    domingo, 19 de junho de 2011 23:27
    Moderador

Todas as Respostas

  • Edivaldo, CTE recursiva é isso: é você poder utilizar a "tabela" que está sendo criada quando ainda está dentro dela. Acho que seria bom um pouco mais de conceito, segundo o BOL:

    "Uma CTE recursiva consiste em três elementos: 

    1) Invocação da rotina.

    A primeira invocação da CTE recursiva consiste em um ou mais CTE_query_definitions associadas pelos operadores UNION ALL, UNION, EXCEPT ou INTERSECT. Como essas definições de consultas constituem o conjunto de resultados base da estrutura da CTE, são citados como membros de ancoragem.

    CTE_query_definitions são considerados membros de ancoragem, exceto se fizerem referência à própria CTE. Todas as definições de consulta de membro de ancoragem devem ser posicionadas antes que a primeira definição de membro recursivo e o operador UNION ALL precisem ser usados para unir o último membro de ancoragem ao primeiro membro recursivo.

    2) Invocação recursiva da rotina.

    A invocação recursiva inclui uma ou mais CTE_query_definitions associadas por operadores UNION ALL que fazem referência à própria CTE. Essas definições de consulta estão denominadas membros recursivos. 

    3) Verificação de término. 

    A verificação de término é implícita; a recursão pára quando nenhuma linha é retornada da invocação anterior."

    E ainda:

    "A estrutura de uma CTE recursiva deve conter no mínimo um membro de ancoragem e um membro recursivo. O pseudocódigo a seguir mostra os componentes de uma CTE recursiva simples que contém um único membro de ancoragem e um único membro recursivo. 

    WITH cte_name ( column_name [,...n] ) AS 

    (

    CTE_query_definition –- Anchor member is defined. 

    UNION ALL 

    CTE_query_definition –- Recursive member is defined referencing cte_name. 

    -- Statement using the CTE 

    SELECT * FROM cte_name"

     

    Fora isso, acredito que a leitura dos artigos do Thiago seriam de total ajuda.

    Parte 1: http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-1/

    Parte 2: http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-2-final/

    Parte 3: http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-3-o-retorno/


    Roberson Ferreira - Database Developer

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    • Sugerido como Resposta Eder Costa segunda-feira, 27 de junho de 2011 18:41
    • Marcado como Resposta Edivaldo Junior quarta-feira, 29 de junho de 2011 20:51
    domingo, 19 de junho de 2011 23:27
    Moderador
  • Edivaldo, conseguiu entender?

    Alguma dúvida? 


    Roberson Ferreira - Database Developer

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    quarta-feira, 22 de junho de 2011 15:24
    Moderador