none
Junção de tabelas com qtd registros diferentes RRS feed

  • Pergunta

  • Boa tarde,

    Sou novo no fórum porém trabalho com básico de SQL a algum tempo.

    Estou com uma dúvida que é a seguinte:

    Tenho duas tabelas: uma de histórico salarial, outra de histórico de função.

    Tabela Histórico Salarial                         Tabela Histórico de Função
    Chapa XYZ - 01/10/10 - Salário 1k              Chapa XYZ - 01/10/10 - Analista Junior
    Chapa XYZ - 01/12/10 - Salário 1,5k           Chapa XYZ - 01/02/11 - Analista Pleno
    Chapa XYZ - 01/01/11 - Salário 2k
    Chapa XYZ - 01/03/11 - Salário 2,5k
    Chapa XYZ - 01/04/11 - Salário 3k

    Preciso juntar essas tabelas da seguinte forma:

    01/10/10 - Salário 1k    - Função Analista Junior
    01/12/10 - Salário 1,5k - Função Analista Junior
    01/01/11 - Salário 2k    - Função Analista Junior
    01/03/11 - Salário 2,5k - Função Analista Pleno
    01/04/11 - Salário 3k    - Função Analista Pleno

    Como podem ver, a única ligação idêntica entre as tabelas é a chapa.
    Se faço a junção com join, não retorna da forma correta =/

    Alguém já passou por isso? Teriam uma idéia?

    No aguardo.

    Obrigado!

    quarta-feira, 28 de novembro de 2012 14:22

Respostas

  • Boa tarde,

    Acho que uma alternativa seria utilizar uma subquery:

    select
        s.Chapa,
        s.Data,
        s.Salario,
        (select top 1 f.Funcao 
         from HistoricoFuncao as f
         where f.Chapa = s.Chapa and
               f.Data <= s.Data
         order by f.Data desc) as Funcao
    from HistoricoSalarial as s

    Espero que ajude.


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

    quarta-feira, 28 de novembro de 2012 16:56

Todas as Respostas

  • Lucas,

    Que join você está usando? 

    Tenta dessa forma:

    Select 
    historicoFuncao.data,
    historicoSalarial.salario,
    historicoFuncao.funcao,
    
    From
    historicoFuncao f
    inner join historicoSalarial s on f.chapa = s.chapa
    
    Where
    f.data = s.data 
    


    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, 28 de novembro de 2012 14:35
  • Boa tarde Marcos Rocha!

    Tentei com inner join mesmo, porém ainda assim não retorna corretamente.

    Pois a data não é idêntica. Tive uma mudança de cargo em 01/02/11, mas o salário continou o mesmo. Mudou apenas o cargo. No exemplo, você pode ver que não há alterações na tabela de salário em 01/02/11.

    Obrigado!

    quarta-feira, 28 de novembro de 2012 14:41
  • Lucas,

    Mas a junção entre as tabelas deverá ser feita através do código do cargo?

    Você poderia postar o seu Select para que possamos avaliar?


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    quarta-feira, 28 de novembro de 2012 16:43
  • Boa tarde,

    Acho que uma alternativa seria utilizar uma subquery:

    select
        s.Chapa,
        s.Data,
        s.Salario,
        (select top 1 f.Funcao 
         from HistoricoFuncao as f
         where f.Chapa = s.Chapa and
               f.Data <= s.Data
         order by f.Data desc) as Funcao
    from HistoricoSalarial as s

    Espero que ajude.


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

    quarta-feira, 28 de novembro de 2012 16:56
  • Boa tarde,

    Segue abaixo o comando:

    SELECT HSTFCO.CHAPA, HSTFCO.CODFUNCAO, HSTSAL.SALARIO
    FROM PFHSTFCO HSTFCO
    INNER JOIN PFHSTSAL HSTSAL ON HSTSAL.CHAPA = HSTFCO.CHAPA
    WHERE HSTFCO.CHAPA = '1019981'

    Sobre a junção, o único item em comum é a chapa. O restante é diferente.

    O que imaginei, mas não consegui fazer, seria fazer uma sub-query, pesquisando na tabela Histórico de Função a data da mudança.

    Ex: A data da tabela histórico salarial é 01/10 (admissão). Logo, sua função é a primeira.
    No caso do histórico do dia 01/03/11 (quando foi alterado o salário) o funcionário já havia sido promovido (porém, mantido o salário), logo, no resultado da query, ele deveria trazer a nova função.

    Tabela Histórico Salarial                         Tabela Histórico de Função
    Chapa XYZ - 01/10/10 - Salário 1k       Chapa XYZ - 01/10/10 - Analista Junior
    Chapa XYZ - 01/12/10 - Salário 1,5k    Chapa XYZ - 01/02/11 - Analista Pleno
    Chapa XYZ - 01/01/11 - Salário 2k
    Chapa XYZ - 01/03/11 - Salário 2,5k
    Chapa XYZ - 01/04/11 - Salário 3k

    01/10/10 - Salário 1k    - Função Analista Junior
    01/12/10 - Salário 1,5k - Função Analista Junior
    01/01/11 - Salário 2k    - Função Analista Junior
    01/03/11 - Salário 2,5k - Função Analista Pleno
    01/04/11 - Salário 3k    - Função Analista Pleno

    Obrigado!

    quarta-feira, 28 de novembro de 2012 17:00
  • Amigo,

    Segue uma solução:

    --Tabelas
    DECLARE @tHistorico TABLE
    (
    Chapa VARCHAR(20),
    Data DATETIME,
    Salario VARCHAR(10)
    )

    DECLARE @tFuncao TABLE
    (
    Chapa VARCHAR(20),
    Data DATETIME,
    Vaga VARCHAR(30)
    )

    --Dados
    INSERT INTO @tHistorico VALUES
    ('XYZ', '20101001', '1k'),
    ('XYZ', '20101201', '1,5k'),
    ('XYZ', '20110101', '2k'),
    ('XYZ', '20110301', '2,5k'),
    ('XYZ', '20110401', '3k')

    INSERT INTO @tFuncao VALUES
    ('XYZ', '20121001', 'An. Junior'),
    ('XYZ', '20110201', 'An. Pleno')

    SELECT a.Data, a.Salario, COALESCE(b.Vaga, d.vaga) As Vaga
    FROM @tHistorico a
    LEFT JOIN @tFuncao b
    ON (a.Chapa = b.Chapa
    AND a.Data BETWEEN (SELECT MAX(c.Data) FROM @tFuncao c WHERE c.Data <= b.Data) AND (SELECT MIN(c.Data) FROM @tFuncao c WHERE c.Data > b.Data)
    )
    LEFT JOIN @tFuncao d
    ON (a.Chapa = d.Chapa
    AND b.Data IS NULL
    AND a.Data < (SELECT MIN(c.Data) FROM @tFuncao c WHERE c.Data < d.Data)
    )


    Fabrizzio A. Caputo
    MCT
    Certificações:
    Oracle OCA 11g
    MCITP SQL Server 2008 Implementation and Maintenance
    MCITP SQL Server 2008 Developer
    Blog Pessoal: www.fabrizziocaputo.wordpress.com
    Blog Empresa: www.tripletech.com.br/blog
    Twitter: @FabrizzioCaputo
    Email: fabrizzio.antoniaci@gmail.com


    quarta-feira, 28 de novembro de 2012 17:19
    Moderador
  • Amigo,

    Segue uma solução:

    --Tabelas
    DECLARE @tHistorico TABLE
    (
    Chapa VARCHAR(20),
    Data DATETIME,
    Salario VARCHAR(10)
    )

    DECLARE @tFuncao TABLE
    (
    Chapa VARCHAR(20),
    Data DATETIME,
    Vaga VARCHAR(30)
    )

    --Dados
    INSERT INTO @tHistorico VALUES
    ('XYZ', '20101001', '1k'),
    ('XYZ', '20101201', '1,5k'),
    ('XYZ', '20110101', '2k'),
    ('XYZ', '20110301', '2,5k'),
    ('XYZ', '20110401', '3k')

    INSERT INTO @tFuncao VALUES
    ('XYZ', '20121001', 'An. Junior'),
    ('XYZ', '20110201', 'An. Pleno')

    SELECT a.Data, a.Salario, COALESCE(b.Vaga, d.vaga) As Vaga
    FROM @tHistorico a
    LEFT JOIN @tFuncao b
    ON (a.Chapa = b.Chapa
    AND a.Data BETWEEN (SELECT MAX(c.Data) FROM @tFuncao c WHERE c.Data <= b.Data) AND (SELECT MIN(c.Data) FROM @tFuncao c WHERE c.Data > b.Data)
    )
    LEFT JOIN @tFuncao d
    ON (a.Chapa = d.Chapa
    AND b.Data IS NULL
    AND a.Data < (SELECT MIN(c.Data) FROM @tFuncao c WHERE c.Data < d.Data)
    )


    Fabrizzio A. Caputo
    MCT
    Certificações:
    Oracle OCA 11g
    MCITP SQL Server 2008 Implementation and Maintenance
    MCITP SQL Server 2008 Developer
    Blog Pessoal: www.fabrizziocaputo.wordpress.com
    Blog Empresa: www.tripletech.com.br/blog
    Twitter: @FabrizzioCaputo
    Email: fabrizzio.antoniaci@gmail.com


    OBS: Editado apenas para remover a CTE, a mesma não é necessaria, foi para alguns testes e acabou ficando no codigo.

    Fabrizzio A. Caputo
    MCT
    Certificações:
    Oracle OCA 11g
    MCITP SQL Server 2008 Implementation and Maintenance
    MCITP SQL Server 2008 Developer
    Blog Pessoal: www.fabrizziocaputo.wordpress.com
    Blog Empresa: www.tripletech.com.br/blog
    Twitter: @FabrizzioCaputo
    Email: fabrizzio.antoniaci@gmail.com

    quarta-feira, 28 de novembro de 2012 17:33
    Moderador
  • Gapimex, valeu!!!

    Sua query funcionou perfeitamente. Da forma que precisava! Muito obrigado!

    Obrigado a todos que ajudaram!

    Abraços!

    quarta-feira, 28 de novembro de 2012 17:35