none
Left Join RRS feed

  • Pergunta

  • Saudações comunidade,

    A consulta abaixo, mostra todos os computadores da minha rede, indicando quais deles possui anti-virus instalado, o "(...)left join ca_software_def (...)" garante que as máquinas sem anti-virus sejam exibidas:

    select distinct har.label, def.name, def.sw_version_label, gen.item_value_text, gen2.item_value_text as nome from ca_discovered_hardware har
    inner join ca_discovered_software soft on har.asset_source_uuid = soft.asset_source_uuid
    left join ca_software_def def on soft.sw_def_uuid = def.sw_def_uuid and def.name like '%antivirus%'
    inner join inv_generalinventory_item gen on gen.object_uuid = har.dis_hw_uuid
    left join ca_itrm.inv_dadoscadastraisiamspe_tree inv on har.dis_hw_uuid = inv.object_uuid
    left join ca_itrm.inv_dadoscadastraisiamspe_item gen2 on gen2.object_uuid = inv.object_uuid and gen2.item_name_id = 390

    where
    gen.item_name_id=17  
    and gen.item_root_name_id=1 
    and gen.item_parent_name_id=5 
    and har.dis_hw_uuid in (
    SELECT object_uuid 
    FROM ca_agent 
    WHERE server_uuid IN (
    SELECT server_uuid 
    FROM ca_server 
    WHERE label='NOME_SERVIDOR'))
    order by 1

    Minha dúvida é que para máquinas com anti-virus recebo 2 linha uma com o nome do anti-virus outra com o campo "name em branco" (exemplo abaixo):

    6-julgamento-01     Windows XP Professional
    6-juridico01     Windows XP Professional
    6-msocial04 avast! Antivirus 6.0.0.0 Windows XP Professional
    6-msocial04 avast! Free Antivirus 6.0.1203.0 Windows XP Professional
    6-msocial04     Windows XP Professional
    6-ncadastro01     Windows XP Professional
    6-ncadastro04     Windows XP Professional
    6-PREVINIR02     Windows XP Professional

    A máquina 6-msocial04 aparece 3 vezes, como faço para exibir apenas a primeira ocorrência, sem perder as linhas em branco das outras máquinas? 

    Observação, filtrei apenas "antivirus", pois as máquinas possuem produtos e versões diferentes.

    Desde já agradeço,

    segunda-feira, 27 de outubro de 2014 18:29

Respostas

  • Boa tarde,

    Márcio, acredito que você pode utilizar a função Row_Number() conforme exemplo do tópico abaixo:

    https://social.msdn.microsoft.com/Forums/sqlserver/pt-BR/fa5a4ed5-3c72-4c3f-b735-b7a2b4865047/select-meio-louco?forum=520

    Espero que ajude.


    Assinatura: http://www.imoveisemexposicao.com.br

    segunda-feira, 27 de outubro de 2014 18:48
  • Acredito que o agrupamento não é necessário.

    Experimente fazer um teste com o script abaixo através do SQL Server Management Studio com e sem a clausula Where da CTE (RN = 1):

    declare @Maquinas table
    (IdMaq int, Nome varchar(30));
    
    insert @Maquinas values
    (1, 'abc'),
    (2, 'def'),
    (3, 'hij');
    
    declare @Observacoes table
    (IdObs int, Observacao varchar(30), IdMaq int);
    
    insert into @Observacoes values
    (1, 'Maq 1 Primeira', 1),
    (2, 'Maq 1 Segunda', 1),
    (3, 'Maq 1 Terceira', 1),
    (4, 'Maq 3 Primeira', 3),
    (5, 'Maq 3 Segunda', 3);
    
    with CTE_RN as
    (
        select
            m.*,
            o.IdObs,
            o.Observacao,
            ROW_NUMBER() OVER(PARTITION BY m.IdMaq ORDER BY o.IdObs) as RN
        from @Maquinas as m
        left join @Observacoes as o
            on o.IdMaq = m.IdMaq    
        
    )
    
    select * from CTE_RN
    where RN = 1

    A função Row_Number() deverá numerar as linhas retornadas pela query da CTE, e a condição final deverá descartar as linhas adicionais.

    Espero que ajude.


    Assinatura: http://www.imoveisemexposicao.com.br

    segunda-feira, 27 de outubro de 2014 20:20

Todas as Respostas

  • Boa tarde,

    Márcio, acredito que você pode utilizar a função Row_Number() conforme exemplo do tópico abaixo:

    https://social.msdn.microsoft.com/Forums/sqlserver/pt-BR/fa5a4ed5-3c72-4c3f-b735-b7a2b4865047/select-meio-louco?forum=520

    Espero que ajude.


    Assinatura: http://www.imoveisemexposicao.com.br

    segunda-feira, 27 de outubro de 2014 18:48
  • Olá Gapimex, obrigado pelo retorno.

    Funcionou, ficou conforme abaixo:

    with CTE as
    (
    select distinct har.label, def.name, def.sw_version_label, gen.item_value_text, gen2.item_value_text as nome, ROW_NUMBER() OVER(PARTITION BY har.label ORDER BY har.label) as RowNum
    from ca_discovered_hardware har
    inner join ca_discovered_software soft on har.asset_source_uuid = soft.asset_source_uuid
    left join ca_software_def def on soft.sw_def_uuid = def.sw_def_uuid and def.name like '%antivirus%'
    inner join inv_generalinventory_item gen on gen.object_uuid = har.dis_hw_uuid
    left join ca_itrm.inv_dadoscadastraisiamspe_tree inv on har.dis_hw_uuid = inv.object_uuid
    left join ca_itrm.inv_dadoscadastraisiamspe_item gen2 on gen2.object_uuid = inv.object_uuid and gen2.item_name_id = 390

    where
    gen.item_name_id=17  
    and gen.item_root_name_id=1 
    and gen.item_parent_name_id=5 
    and har.dis_hw_uuid in (
    SELECT object_uuid 
    FROM ca_agent 
    WHERE server_uuid IN (
    SELECT server_uuid 
    FROM ca_server 
    WHERE label='nome_servidor')) 
    group by har.label, def.name, def.sw_version_label, gen.item_value_text, gen2.item_value_text

    )

    select * from CTE
    where RowNum = 1

    Muito obrigado, grande abraço.

    segunda-feira, 27 de outubro de 2014 19:18
  • Olá Márcio,

    Você utilizou a função Row_Number()?

    Você pode postar como ficou a sua query com as alterações?

    Acredito que deveria funcionar...


    Assinatura: http://www.imoveisemexposicao.com.br

    segunda-feira, 27 de outubro de 2014 19:28
  • Eu deveria ter agrupado antes, por isso não havia funcionado, depois que agrupei por "label" funcionou.

    Muito Obrigado,

    segunda-feira, 27 de outubro de 2014 19:59
  • Acredito que o agrupamento não é necessário.

    Experimente fazer um teste com o script abaixo através do SQL Server Management Studio com e sem a clausula Where da CTE (RN = 1):

    declare @Maquinas table
    (IdMaq int, Nome varchar(30));
    
    insert @Maquinas values
    (1, 'abc'),
    (2, 'def'),
    (3, 'hij');
    
    declare @Observacoes table
    (IdObs int, Observacao varchar(30), IdMaq int);
    
    insert into @Observacoes values
    (1, 'Maq 1 Primeira', 1),
    (2, 'Maq 1 Segunda', 1),
    (3, 'Maq 1 Terceira', 1),
    (4, 'Maq 3 Primeira', 3),
    (5, 'Maq 3 Segunda', 3);
    
    with CTE_RN as
    (
        select
            m.*,
            o.IdObs,
            o.Observacao,
            ROW_NUMBER() OVER(PARTITION BY m.IdMaq ORDER BY o.IdObs) as RN
        from @Maquinas as m
        left join @Observacoes as o
            on o.IdMaq = m.IdMaq    
        
    )
    
    select * from CTE_RN
    where RN = 1

    A função Row_Number() deverá numerar as linhas retornadas pela query da CTE, e a condição final deverá descartar as linhas adicionais.

    Espero que ajude.


    Assinatura: http://www.imoveisemexposicao.com.br

    segunda-feira, 27 de outubro de 2014 20:20