none
ATUALIZAR TABELA A SELECIONANDO OS DADOS COM A MAIOR NOTA NA TABELA B RRS feed

  • Pergunta

  • Srs, tenho uma tabela A no seguinte formato:

    DOC DDD   TELEFONE NOTA
    849138 64 992567386   34
    849138 65 992602435 86
    849138 65 999060387 100
    849138 81 993111764 44
    1841017   53 991175716 33
    1841017 53 997045733 34
    1841017 53 999915113 30


    Preciso atualizar a tabela B que tem este layout:

    DOC DDD1 TELEFONE1    DDD2 TELEFONE2

    

    O critério é selecionar somente os 2 telefones com maior nota, então o resutado seria este:

    DOC DDD1 TELEFONE1   DDD2 TELEFONE2
    849138 65 999060387    65 992602435
    1841017 53 997045733    53 991175716

    como codifico, por favor?

    sábado, 7 de dezembro de 2019 17:55

Respostas

  • José no caso eu preciso ATUALIZAR mesmo o valor da tabela B e não inserir.
    A tabela B já tem o DOC correspondente, preciso fazer o update selecionando o tel com nota mais alta.

    Ok.

    O código #3 está preparado para atualizar e também incluir, caso não exista linha com valor de DOC em TABELA_B. Mas se quiser um código SQL que somente atualize, eis outra sugestão:

    -- código #4
    with
    PASSO1 as (
    SELECT DOC, DDD, TELEFONE, NOTA,
           seq= row_number() over (partition by DOC order by NOTA desc)
      from TABELA_A
    ),
    PASSO2 as (
    SELECT DOC,    
           max (case when seq = 1 then DDD end) as DDD1,
           max (case when seq = 1 then TELEFONE end) as TELEFONE1,
           max (case when seq = 2 then DDD end) as DDD2,
           max (case when seq = 2 then TELEFONE end) as TELEFONE2
      from PASSO1
      group by DOC
    )
    UPDATE B
      set DDD1= A.DDD1, TELEFONE1= A.TELEFONE1, DDD2= A.DDD2, TELEFONE2= A.TELEFONE2
      from TABELA_B as B
           inner join PASSO2 as A on A.DOC = B.DOC;

     

     

    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Sugerido como Resposta José Diz segunda-feira, 9 de dezembro de 2019 13:02
    • Marcado como Resposta IgorFKModerator segunda-feira, 9 de dezembro de 2019 13:14
    • Editado José Diz segunda-feira, 9 de dezembro de 2019 13:59
    domingo, 8 de dezembro de 2019 22:19

Todas as Respostas

  •  
    Valdinei, para obter o resultado conforme leiaute que informou, uma opção é
     

    -- código #1
    with TABELA as (
    SELECT DOC, DDD, TELEFONE, NOTA,
           seq= row_number() over (partition by DOC order by NOTA desc)
      from TABELA_A
    )         
    SELECT DOC,	
           max (case when seq = 1 then DDD end) as DDD1,
           max (case when seq = 1 then TELEFONE end) as TELEFONE1,
           max (case when seq = 2 then DDD end) as DDD2,
           max (case when seq = 2 then TELEFONE end) as TELEFONE2
      from TABELA
      group by DOC;

    O código acima utiliza o conceito de pivô clássico para criar as duas colunas DDD/TELEFONE por linha; detalhes no artigo “Alas & Pivôs”.

     

    A respeito de "atualizar a tabela B", signiifica "alterar valor do que já existe" ou inserir as linhas?

    -- código #3
    with
    PASSO1 as (
    SELECT DOC, DDD, TELEFONE, NOTA,
           seq= row_number() over (partition by DOC order by NOTA desc)
      from TABELA_A
    ),
    PASSO2 as (
    SELECT DOC,    
           max (case when seq = 1 then DDD end) as DDD1,
           max (case when seq = 1 then TELEFONE end) as TELEFONE1,
           max (case when seq = 2 then DDD end) as DDD2,
           max (case when seq = 2 then TELEFONE end) as TELEFONE2
      from PASSO1
      group by DOC
    )
    MERGE
       into TABELA_B as B
       using PASSO2 as A
       on A.DOC = B.DOC
       when matched then
            UPDATE set DDD1= A.DDD1, TELEFONE1= A.TELEFONE1, DDD2= A.DDD2, TELEFONE2= A.TELEFONE2
       when not matched by target then
            INSERT (DOC, DDD1, TELEFONE1, DDD2, TELEFONE2)
              values (A.DOC, A.DDD1, A.TELEFONE1, A.DDD2, A.TELEFONE2);

     

    O código acima utiliza o conceito de CTE encadeada para tornar a programação modular; detalhes no artigo “Programação modular com expressões de tabela (CTE)”. A primeira CTE, PASSO1, numera as linhas da tabela original segundo o critério definido para encontrar as duas maiores notas; a segnda CTE, PASSO2, utiliza o pivô clássico para montar as linhas conforme leiaute de "TABELA B"; e finalmente o comando MERGE, que atualiza "TABELA B".

     


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz segunda-feira, 9 de dezembro de 2019 13:59
    sábado, 7 de dezembro de 2019 19:08
  • José no caso eu preciso ATUALIZAR mesmo o valor da tabela B e não inserir.

    A tabela B já tem o DOC correspondente, preciso fazer o update selecionando o tel com nota mais alta.

    domingo, 8 de dezembro de 2019 21:04
  • Deu certo Luiz, perfeito, valeu mesmo
    domingo, 8 de dezembro de 2019 21:53
  • José no caso eu preciso ATUALIZAR mesmo o valor da tabela B e não inserir.
    A tabela B já tem o DOC correspondente, preciso fazer o update selecionando o tel com nota mais alta.

    Ok.

    O código #3 está preparado para atualizar e também incluir, caso não exista linha com valor de DOC em TABELA_B. Mas se quiser um código SQL que somente atualize, eis outra sugestão:

    -- código #4
    with
    PASSO1 as (
    SELECT DOC, DDD, TELEFONE, NOTA,
           seq= row_number() over (partition by DOC order by NOTA desc)
      from TABELA_A
    ),
    PASSO2 as (
    SELECT DOC,    
           max (case when seq = 1 then DDD end) as DDD1,
           max (case when seq = 1 then TELEFONE end) as TELEFONE1,
           max (case when seq = 2 then DDD end) as DDD2,
           max (case when seq = 2 then TELEFONE end) as TELEFONE2
      from PASSO1
      group by DOC
    )
    UPDATE B
      set DDD1= A.DDD1, TELEFONE1= A.TELEFONE1, DDD2= A.DDD2, TELEFONE2= A.TELEFONE2
      from TABELA_B as B
           inner join PASSO2 as A on A.DOC = B.DOC;

     

     

    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Sugerido como Resposta José Diz segunda-feira, 9 de dezembro de 2019 13:02
    • Marcado como Resposta IgorFKModerator segunda-feira, 9 de dezembro de 2019 13:14
    • Editado José Diz segunda-feira, 9 de dezembro de 2019 13:59
    domingo, 8 de dezembro de 2019 22:19
  • Eu tinha comentado a linha do "no matched" e tinha dado certo, mas legal esta outra opção, o código ficou mais clean.

    Show, valeu mesmo

    segunda-feira, 9 de dezembro de 2019 10:27