none
Dúvida na construção de um comando SELECT RRS feed

  • Pergunta

  • Boa tarde a todos. Essa é uma dúvida antiga que tenho sobre SQL Server.
    Supondo que tenho 3 tabelas. Quero carregar as informações de um conteúdo,  seus conteúdos relacionados e anexos ( que poderiam ser fotos, por exemplo ).

    Tabela Conteudos:
    cont_cod   cont_titulo
    1               cont1
    2               cont2
    3               cont3
    4               cont4

    Tabela ConteudosRelacionados:

    cont_cod cont_relacionado
    1               3
    1               2
    1               4
    2               1
    2               3

    Tabela AnexosConteudos:
    anexo_cod    cont_cod    anexo_arquivo
    1                   3                 foto.jpg     
    2                   2                 arvore.png     
    3                   1                 teste.jpg     
    4                   4                123.jpg     

    Certo. A idéia seria com o cont_cod como parâmetro trazer o titulo da tabela Conteudo, apenas 1 anexo_arquivo da tabela AnexosConteudos e o cont_relacionado da tabela ConteudosRelacionados.

    Fazendo dessa forma:

    SELECT DISTINCT TOP (3) ConteudosRelacionados.cont_relacionado, Conteudos.cont_titulo, 
                    (select top 1 anexo_arquivo from AnexosConteudos where AnexosConteudos.cont_cod = 1) as anexo
    FROM              ConteudosRelacionados INNER JOIN
                      Conteudos ON ConteudosRelacionados.cont_relacionado = Conteudos.cont_cod                   
    WHERE     (ConteudosRelacionados.cont_cod = 1)
    group by cont_relacionado, cont_titulo

    Eu recebo esse resultado:

    cont_relacionado cont_titulo anexo
    2 cont2 foto.jpg
    3 cont3 foto.jpg
    4 cont4 foto.jpg

    Os anexos ficam duplicados. Pois bem, queria saber como fazer essa query sem receber resultados duplicados. Trazendo o cont_relacionado o cont_titulo e apenas 1 anexo de cada conteúdo.

    Abraços...


    Evandro Aguiar
    http://wta3.com.br

    Farei o possível, para ajudar. Caso eu consiga, marque minha resposta como útil e me faça feliz. :) hauhauhauhauh



    • Editado EvandroAS sexta-feira, 3 de agosto de 2012 15:45
    sexta-feira, 3 de agosto de 2012 15:43

Respostas

  • Evandro

    o resultado desejado seria assim:

    2                  cont2        foto.jpg 
    3                  cont3       
    4                  cont4
    5                  cont5        foto5.jpg       

    Aparece o nome apenas 1 vez?


    Att.
    Marcelo Fernandes

    MCP, MCDBA, MCSA, MCTS.
    Se útil, classifique!!!
    Me siga no twitter: @marcelodba

    Sim, trazendo apenas um anexo pra cada conteúdo. Fiquei aqui tentando e descobri uma forma:

    SELECT DISTINCT TOP (4) ConteudosRelacionados.cont_relacionado, Conteudos.cont_titulo, 
                          max(AnexosConteudos.anexo_arquivo) as anexo_arquivo
    FROM         ConteudosRelacionados INNER JOIN
                          Conteudos ON ConteudosRelacionados.cont_relacionado = Conteudos.cont_cod INNER JOIN
                          AnexosConteudos ON ConteudosRelacionados.cont_relacionado = AnexosConteudos.cont_cod
    WHERE     (ConteudosRelacionados.cont_cod = '1')
    group by ConteudosRelacionados.cont_relacionado, Conteudos.cont_titulo

    Utilizando Distinct, top e group by acabou dando certo. :)


    Evandro Aguiar
    http://wta3.com.br

    Farei o possível, para ajudar. Caso eu consiga, marque minha resposta como útil e me faça feliz. :) hauhauhauhauh

    • Marcado como Resposta EvandroAS sexta-feira, 3 de agosto de 2012 19:21
    sexta-feira, 3 de agosto de 2012 17:40
  • Evandro

    segue uma outra maneira,acredito que até mais performatica usando CTE

    declare @tbConteudo as table (cont_cod int, cont_titulo varchar(10))
    insert into @tbConteudo values (1, 'cont1'),(2, 'cont2'),(3, 'cont3'),(4, 'cont4')
    declare @tbContRelacionado as table (cont_cod int, cont_relacionado int)
    insert into @tbContRelacionado values (1,3),(1,2),(1,4),(2,1),(2,3)
    declare @tbAnexosConteudos as table (anexo_cod int, cont_cod int, anexo_arquivo varchar(10))
    insert into @tbAnexosConteudos values (1,3,'foto.jpg'),(2,2,'arvore.png'),(3,1,'teste.jpg'),(4,4,'123.jpg')
    ;with cte_teste
    as
    (
    select cont_relacionado, cont_titulo, anexo_arquivo, row_number() over(partition by anexo_arquivo order by anexo_arquivo,cont_relacionado, cont_titulo) contador
    FROM              @tbContRelacionado cr INNER JOIN
                      @tbConteudo c ON cr.cont_relacionado = c.cont_cod    
                      INNER JOIN @tbAnexosConteudos ac ON ac.cont_cod = cr.cont_cod
    WHERE     (cr.cont_cod = 1)
    group by cont_relacionado, cont_titulo,anexo_arquivo
    )
    select cont_relacionado, cont_titulo, case when contador = 1 then anexo_arquivo else '' end anexo from cte_teste


    Att.
    Marcelo Fernandes

    MCP, MCDBA, MCSA, MCTS.
    Se útil, classifique!!!
    Me siga no twitter: @marcelodba

    • Marcado como Resposta EvandroAS sexta-feira, 3 de agosto de 2012 19:21
    sexta-feira, 3 de agosto de 2012 18:29
    Moderador

Todas as Respostas

  • Evandro

    o resultado desejado seria assim:

    2                  cont2        foto.jpg 
    3                  cont3       
    4                  cont4
    5                  cont5        foto5.jpg       

    Aparece o nome apenas 1 vez?


    Att.
    Marcelo Fernandes

    MCP, MCDBA, MCSA, MCTS.
    Se útil, classifique!!!
    Me siga no twitter: @marcelodba

    sexta-feira, 3 de agosto de 2012 16:52
    Moderador
  • Evandro

    o resultado desejado seria assim:

    2                  cont2        foto.jpg 
    3                  cont3       
    4                  cont4
    5                  cont5        foto5.jpg       

    Aparece o nome apenas 1 vez?


    Att.
    Marcelo Fernandes

    MCP, MCDBA, MCSA, MCTS.
    Se útil, classifique!!!
    Me siga no twitter: @marcelodba

    Sim, trazendo apenas um anexo pra cada conteúdo. Fiquei aqui tentando e descobri uma forma:

    SELECT DISTINCT TOP (4) ConteudosRelacionados.cont_relacionado, Conteudos.cont_titulo, 
                          max(AnexosConteudos.anexo_arquivo) as anexo_arquivo
    FROM         ConteudosRelacionados INNER JOIN
                          Conteudos ON ConteudosRelacionados.cont_relacionado = Conteudos.cont_cod INNER JOIN
                          AnexosConteudos ON ConteudosRelacionados.cont_relacionado = AnexosConteudos.cont_cod
    WHERE     (ConteudosRelacionados.cont_cod = '1')
    group by ConteudosRelacionados.cont_relacionado, Conteudos.cont_titulo

    Utilizando Distinct, top e group by acabou dando certo. :)


    Evandro Aguiar
    http://wta3.com.br

    Farei o possível, para ajudar. Caso eu consiga, marque minha resposta como útil e me faça feliz. :) hauhauhauhauh

    • Marcado como Resposta EvandroAS sexta-feira, 3 de agosto de 2012 19:21
    sexta-feira, 3 de agosto de 2012 17:40
  • Evandro,

    você precisa de um inner join entre as 3 tabelas tendo como filtro o campo cont_cod além de especificar qual conteúdo você quer informações por meio da cláusula where.

    É isto:?

    SELECT
              cr.cont_relacionado,
              c.cont_titulo,
              ac.anexo_arquivo
    FROM conteudo  c
                  INNER JOIN conteudo_relacionado cr
                      ON c.cont_cod = cr.cont_cod
                  INNER JOIN anexos_conteudos ac
                       ON c.cont_cod = ac.cont_cod
    -- definindo o codigo do conteudo ao qual você quer informações ( 1 )
    WHERE
               C.COD_CONT = 1;

    sexta-feira, 3 de agosto de 2012 18:27
  • Evandro

    segue uma outra maneira,acredito que até mais performatica usando CTE

    declare @tbConteudo as table (cont_cod int, cont_titulo varchar(10))
    insert into @tbConteudo values (1, 'cont1'),(2, 'cont2'),(3, 'cont3'),(4, 'cont4')
    declare @tbContRelacionado as table (cont_cod int, cont_relacionado int)
    insert into @tbContRelacionado values (1,3),(1,2),(1,4),(2,1),(2,3)
    declare @tbAnexosConteudos as table (anexo_cod int, cont_cod int, anexo_arquivo varchar(10))
    insert into @tbAnexosConteudos values (1,3,'foto.jpg'),(2,2,'arvore.png'),(3,1,'teste.jpg'),(4,4,'123.jpg')
    ;with cte_teste
    as
    (
    select cont_relacionado, cont_titulo, anexo_arquivo, row_number() over(partition by anexo_arquivo order by anexo_arquivo,cont_relacionado, cont_titulo) contador
    FROM              @tbContRelacionado cr INNER JOIN
                      @tbConteudo c ON cr.cont_relacionado = c.cont_cod    
                      INNER JOIN @tbAnexosConteudos ac ON ac.cont_cod = cr.cont_cod
    WHERE     (cr.cont_cod = 1)
    group by cont_relacionado, cont_titulo,anexo_arquivo
    )
    select cont_relacionado, cont_titulo, case when contador = 1 then anexo_arquivo else '' end anexo from cte_teste


    Att.
    Marcelo Fernandes

    MCP, MCDBA, MCSA, MCTS.
    Se útil, classifique!!!
    Me siga no twitter: @marcelodba

    • Marcado como Resposta EvandroAS sexta-feira, 3 de agosto de 2012 19:21
    sexta-feira, 3 de agosto de 2012 18:29
    Moderador
  • Evandro

    segue uma outra maneira,acredito que até mais performatica usando CTE

    declare @tbConteudo as table (cont_cod int, cont_titulo varchar(10))
    insert into @tbConteudo values (1, 'cont1'),(2, 'cont2'),(3, 'cont3'),(4, 'cont4')
    declare @tbContRelacionado as table (cont_cod int, cont_relacionado int)
    insert into @tbContRelacionado values (1,3),(1,2),(1,4),(2,1),(2,3)
    declare @tbAnexosConteudos as table (anexo_cod int, cont_cod int, anexo_arquivo varchar(10))
    insert into @tbAnexosConteudos values (1,3,'foto.jpg'),(2,2,'arvore.png'),(3,1,'teste.jpg'),(4,4,'123.jpg')
    ;with cte_teste
    as
    (
    select cont_relacionado, cont_titulo, anexo_arquivo, row_number() over(partition by anexo_arquivo order by anexo_arquivo,cont_relacionado, cont_titulo) contador
    FROM              @tbContRelacionado cr INNER JOIN
                      @tbConteudo c ON cr.cont_relacionado = c.cont_cod    
                      INNER JOIN @tbAnexosConteudos ac ON ac.cont_cod = cr.cont_cod
    WHERE     (cr.cont_cod = 1)
    group by cont_relacionado, cont_titulo,anexo_arquivo
    )
    select cont_relacionado, cont_titulo, case when contador = 1 then anexo_arquivo else '' end anexo from cte_teste


    Att.
    Marcelo Fernandes

    MCP, MCDBA, MCSA, MCTS.
    Se útil, classifique!!!
    Me siga no twitter: @marcelodba

    Nossa, ficou complicado isso aí. rs... Mas é uma opção.

    Evandro Aguiar
    http://wta3.com.br

    Farei o possível, para ajudar. Caso eu consiga, marque minha resposta como útil e me faça feliz. :) hauhauhauhauh


    • Editado EvandroAS sexta-feira, 3 de agosto de 2012 19:22
    sexta-feira, 3 de agosto de 2012 19:21