none
Junção de 02 Query RRS feed

  • Pergunta

  • Boa tarde

     

     

     

    ---EXTRAINDO OS DADOS PARA A CLIENTES

     

    SELECT id_cliente, nome, sexo, data_nascimento, razao_social, nome_fantasia, setor_economico

    INTO #CLIENTES

    FROM CALL_CENTER_OLTP.DBO.ASSOCIADOS ASSOCIADOS,

    CALL_CENTER_OLTP.DBO.CLIENTES CLIENTES

    WHERE ASSOCIADOS.id_associado = CLIENTES.id_associado

     

    --Inserinfo dados na dimensao Clientes

     

    INSERT INTO dimensao_cliente (nome, sexo, maior_de_idade, dimensao_empresa_id_empresa)

    SELECT DISTINCT nome, descricao_sexo, eh_maior_idade, id_empresa

    FROM #CLIENTES, dimensao_empresa

    WHERE ( #CLIENTES.razao_social = dimensao_empresa.razao_social )

    AND NOT EXISTS ( SELECT * FROM dimensao_cliente

    WHERE dimensao_cliente.nome = #CLIENTES.nome)

     

    A primeira query pega os dados de banco de dados(CRM)das  tabela clientes e Associados  e insere e um tabela temporaria #CLIENTES.

    A segunda query pega esse dados da tabela Temporaria(#cliente) e joga em uma outro banco de Dados(CRM_DW) na tabela Dimensao_cliente.

     

    Como juntas essa dus query sem usar uma tabela temporaria ?

     

    Agradeço

    segunda-feira, 10 de novembro de 2008 17:13

Respostas

  • INSERT INTO dimensao_cliente (nome, sexo, maior_de_idade, dimensao_empresa_id_empresa)
    SELECT DISTINCT nome, descricao_sexo, eh_maior_idade, id_empresa
    FROM (SELECT id_cliente, nome, sexo, data_nascimento, razao_social, nome_fantasia, setor_economico
            FROM CALL_CENTER_OLTP.DBO.ASSOCIADOS ASSOCIADOS,CALL_CENTER_OLTP.DBO.CLIENTES CLIENTES
            WHERE ASSOCIADOS.id_associado = CLIENTES.id_associado) As Tab
    INNER JOIN dimensao_empresa
    ON (Tab.razao_social = dimensao_empresa.razao_social)
    WHERE NOT EXISTS ( SELECT * FROM dimensao_cliente
    WHERE dimensao_cliente.nome = Tab.nome)
    segunda-feira, 10 de novembro de 2008 17:29
  • Boa Noite,

     

    Acredito que uma CTE vá de encontro a clareza do código e a sua necessidade. Tente o código abaixo:

     

    Code Snippet

    WITH CLIENTES AS (

    SELECT id_cliente, nome, sexo, data_nascimento, razao_social, nome_fantasia, setor_economico

    FROM CALL_CENTER_OLTP.DBO.ASSOCIADOS ASSOCIADOS,

    CALL_CENTER_OLTP.DBO.CLIENTES CLIENTES

    WHERE ASSOCIADOS.id_associado = CLIENTES.id_associado)

     

    INSERT INTO dimensao_cliente (nome, sexo, maior_de_idade, dimensao_empresa_id_empresa)

    SELECT DISTINCT nome, descricao_sexo, eh_maior_idade, id_empresa

    FROM CLIENTES, dimensao_empresa

    WHERE ( CLIENTES.razao_social = dimensao_empresa.razao_social )

    AND NOT EXISTS ( SELECT * FROM dimensao_cliente

    WHERE dimensao_cliente.nome = CLIENTES.nome)

     

     

    [ ]s,

     

    Gustavo

    segunda-feira, 10 de novembro de 2008 20:46

Todas as Respostas

  • INSERT INTO dimensao_cliente (nome, sexo, maior_de_idade, dimensao_empresa_id_empresa)
    SELECT DISTINCT nome, descricao_sexo, eh_maior_idade, id_empresa
    FROM (SELECT id_cliente, nome, sexo, data_nascimento, razao_social, nome_fantasia, setor_economico
            FROM CALL_CENTER_OLTP.DBO.ASSOCIADOS ASSOCIADOS,CALL_CENTER_OLTP.DBO.CLIENTES CLIENTES
            WHERE ASSOCIADOS.id_associado = CLIENTES.id_associado) As Tab
    INNER JOIN dimensao_empresa
    ON (Tab.razao_social = dimensao_empresa.razao_social)
    WHERE NOT EXISTS ( SELECT * FROM dimensao_cliente
    WHERE dimensao_cliente.nome = Tab.nome)
    segunda-feira, 10 de novembro de 2008 17:29
  • Boa Tarde,

     

    Seu SQL Server é 2005 ?

     

    [ ]s,

     

    Gustavo

     

    segunda-feira, 10 de novembro de 2008 17:45
  • VOU TESTAR...

    segunda-feira, 10 de novembro de 2008 17:53
  • sql 2005

     

    segunda-feira, 10 de novembro de 2008 19:42
  • Boa Noite,

     

    Acredito que uma CTE vá de encontro a clareza do código e a sua necessidade. Tente o código abaixo:

     

    Code Snippet

    WITH CLIENTES AS (

    SELECT id_cliente, nome, sexo, data_nascimento, razao_social, nome_fantasia, setor_economico

    FROM CALL_CENTER_OLTP.DBO.ASSOCIADOS ASSOCIADOS,

    CALL_CENTER_OLTP.DBO.CLIENTES CLIENTES

    WHERE ASSOCIADOS.id_associado = CLIENTES.id_associado)

     

    INSERT INTO dimensao_cliente (nome, sexo, maior_de_idade, dimensao_empresa_id_empresa)

    SELECT DISTINCT nome, descricao_sexo, eh_maior_idade, id_empresa

    FROM CLIENTES, dimensao_empresa

    WHERE ( CLIENTES.razao_social = dimensao_empresa.razao_social )

    AND NOT EXISTS ( SELECT * FROM dimensao_cliente

    WHERE dimensao_cliente.nome = CLIENTES.nome)

     

     

    [ ]s,

     

    Gustavo

    segunda-feira, 10 de novembro de 2008 20:46
  • Maia,

     

    Só não entendi o porque você não utilizou Inner Join, e prefirou trabalhar com este ou padrão, alguma coisa em especialmente, ou foi para facilitar o entendimento ao nosso colega?

    terça-feira, 11 de novembro de 2008 10:08
  • Oi Jr.

     

    De fato eu basicamente fiz a transposição da consulta para uma CTE e não me atentei para a junção. Com certeza junções com JOINs são mais recomendadas, mas acredito que se a idéia é melhorar, nem o JOIN seria necessário. Um Exists iria melhorar ainda mais, inclusive retirando o DISTINCT. Acredito que o exemplo abaixo seja o mais indicado:

     

    Code Snippet

    WITH CLIENTES AS (

    SELECT id_cliente, nome, sexo, data_nascimento, razao_social, nome_fantasia, setor_economico

    FROM CALL_CENTER_OLTP.DBO.ASSOCIADOS ASSOCIADOS,

    CALL_CENTER_OLTP.DBO.CLIENTES CLIENTES

    WHERE ASSOCIADOS.id_associado = CLIENTES.id_associado)

     

    INSERT INTO dimensao_cliente (nome, sexo, maior_de_idade, dimensao_empresa_id_empresa)

    SELECT nome, descricao_sexo, eh_maior_idade, id_empresa

    FROM CLIENTES

    WHERE

    EXISTS (SELECT * from dimensao_empresa WHERE CLIENTES.razao_social = dimensao_empresa.razao_social)

    AND NOT EXISTS ( SELECT * FROM dimensao_cliente

    WHERE dimensao_cliente.nome = CLIENTES.nome)

     

    [ ]s,

     

    Gustavo

    terça-feira, 11 de novembro de 2008 11:44
  •  

    apareceu essa mensagem quando vou rodar o script

     

    Msg 208, Level 16, State 1, Line 1

    Invalid object name 'dimensao_cliente'.

     

    terça-feira, 11 de novembro de 2008 16:05
  • Olá Gildo,

     

    Copiei esse nome de seu script. Verifique se o mesmo está correto e se você está no banco certo e tente novamente.

     

    [ ]s,

     

    Gustavo

    terça-feira, 11 de novembro de 2008 16:20
  •  

    vc poderia me exlicar melhor esse comando WITH ????????????

     

    Essa seria a melhor maneira de tirar a tabela temporaria entre essas Query ???. Pois tem varios exemplos que preciso fazer isso, e tem caso que antes de inserir em outro banco de dados, preciso fazer o tratamento dos registros, por exemplo: 

     

     

    ALTER TABLE #ATENDENTES ADD descricao_sexo varchar(10), nome_localidade varchar(50), sigla_estado varchar(2)

     

    UPDATE #ATENDENTES SET descricao_sexo = 'Masculino'

    WHERE sexo = 'M'

     

    UPDATE #ATENDENTES SET descricao_sexo = 'Feminino'

    WHERE sexo = 'F'

     

    como ficaria em uma unica procedure ?

     

    Seria grato,

     

    terça-feira, 11 de novembro de 2008 16:45
  • Boa Tarde,

     

    Postei uma observação no outro post.

     

    Se você vai alterar uma estrutura, então a CTE não será útil para adicionar essas colunas. Em todo caso não tínhamos como saber, pois, o script anterior não demonstrava esses comandos de alteração. Ainda assim eu optaria pela CTE e calcularia esses campos. Ex:

     

    SELECT *, CASE SEXO WHEN 'M' THEN 'Masculinho' ELSE 'Feminino' END AS Descricao_Sexo FROM CTE

     

    Evite utilizar tabelas temporárias em processamentos de carga. Elas vão retardar o processo. Podem ter alguns benefícios na clareza do processo mas nem sempre eles compensam o Overhead de escrita (principalmente para tabelas muito grandes)

     

    Suas dúvidas são muitos semelhantes. Que tal se mantivéssemos as dúvidas no mesmo post ?

     

    [ ]s,

     

    Gustavo

    terça-feira, 11 de novembro de 2008 17:06
  •  

    Desculpa Gustavo, por não ter postado esse tratamento antes, pois a dúvida vai surgindo a medida que vou fazer as query. Entao poderia usar esse Script dentro de uma procedure antes de inserir em outro banco ? Como ficaria essa query com a anterior que vc postou dentro de uma Stored Procedure. Desculpa mais uma vez. Pois sou um pouco inciantes nisso.

     

    SELECT *, CASE SEXO WHEN 'M' THEN 'Masculinho' ELSE 'Feminino' END AS Descricao_Sexo FROM CTE

     

     

    Grato...

    terça-feira, 11 de novembro de 2008 17:23
  • Oi Gildo,

     

    A CTE (Common Table Expression) é definida no WITH e é um objeto como uma tabela. Basta colocar um CASE. Adaptando o seu script temos:

     

    Code Snippet

    WITH CLIENTES AS (

    SELECT id_cliente, nome, sexo, data_nascimento, razao_social, nome_fantasia, setor_economico

    FROM CALL_CENTER_OLTP.DBO.ASSOCIADOS ASSOCIADOS,

    CALL_CENTER_OLTP.DBO.CLIENTES CLIENTES

    WHERE ASSOCIADOS.id_associado = CLIENTES.id_associado)

     

    INSERT INTO dimensao_cliente (nome, sexo, maior_de_idade, dimensao_empresa_id_empresa)

    SELECT DISTINCT nome,

    case sexo when 'm' then 'masculino' else 'feminino' end

    , eh_maior_idade, id_empresa

    FROM CLIENTES, dimensao_empresa

    WHERE ( CLIENTES.razao_social = dimensao_empresa.razao_social )

    AND NOT EXISTS ( SELECT * FROM dimensao_cliente

    WHERE dimensao_cliente.nome = CLIENTES.nome)

     

    Colocar esse caso é bem mais eficiente do que escrever em uma tabela temporária e atualizar as descrições.

     

    [ ]s,

     

    Gustavo

    terça-feira, 11 de novembro de 2008 18:01
  • Gustavo

     

    Bom dia

     

                   Nos Posts anteriores vc me ensinou a suar o comando With(não precisava usar a tabela temporaria). Posso usar esse comando para referenciar mais de uma tabela ? Estou com essa situação abaixo.Tenho agora varias tabelas temporarias. Os Comando que vc me ensinou WITH, funcioou certinho, quando eu tinha somente uma tabela temporaria.

     

    Grato,

     

    INSERT INTO Fato_Chamados(dimensao_status_id_status, dimensao_dia_id_tempo,

    dimensao_cliente_id_cliente, dimensao_atendente_id_atendente, quantidade, duracao)

    SELECT dimensao_status.id_status, dimensao_dia.id_tempo, dimensao_cliente.id_cliente,

    dimensao_atendente.id_atendente, 1, duracao

    FROM #CHAMADAS, #DATAS, #ATENDENTES, #STATUS, #CLIENTES,

    dimensao_dia, dimensao_mes, dimensao_atendente, dimensao_status, dimensao_cliente, dimensao_empresa,

    dimensao_central

    WHERE (#CHAMADAS.id_funcionario = #ATENDENTES.id_funcionario)

    AND (#CHAMADAS.id_cliente = #CLIENTES.id_cliente)

    AND (#CHAMADAS.id_status_chamada = #STATUS.id_status_chamada)

    AND (#CHAMADAS.data_hora_inicio = #DATAS.data_hora_inicio)

    AND (#STATUS.descricao = dimensao_status.descricao)

    AND (#ATENDENTES.nome = dimensao_atendente.nome)

    AND (#ATENDENTES.nome_localidade = dimensao_central.localidade AND #ATENDENTES.sigla_estado = dimensao_central.sigla_estado)

    AND (dimensao_atendente.dimensao_central_id_central = dimensao_central.id_central)

    AND (#CLIENTES.razao_social = dimensao_empresa.razao_social)

    AND (#CLIENTES.nome = dimensao_cliente.nome)

    AND (dimensao_cliente.dimensao_empresa_id_empresa = dimensao_empresa.id_empresa)

    AND (#DATAS.dia = dimensao_dia.dia)

    AND (#DATAS.ano = dimensao_mes.ano AND #DATAS.mes = dimensao_mes.mes)

    AND (dimensao_dia.dimensao_mes_id_mes = dimensao_mes.id_mes)

     

     

    quinta-feira, 13 de novembro de 2008 12:08
  • Bom Dia,

     

    Sim. É possível utilizar quantas tabelas você desejar (no artigo que lhe indique inclusive tem um exemplo desses usando um JOIN dentro de uma CTE). Você poderá inclusive reaproveitar CTEs. Ex:

     

    WITH CTE1 AS (<Coloque aqui o seu SELECT>),

    CTE2 AS (<Coloque aqui o seu SELECT>),

    CTE3 AS (<Coloque aqui o seu SELECT>),

    CTE4 AS (<SELECTs combinados das CTEs 1, 2 e 3)

     

    SELECT <Campos> FROM CTE4

     

    [ ]s,

     

    Gustavo

     

    quinta-feira, 13 de novembro de 2008 12:29
  • Gustavo.. eu conseguir relacionar as minhas tabelas como o comando Whith, como vc me ensinou. Quando vou executar essa procedure, a mesma fica demorando um bom tempo e não executa. Preciso dar um stop para terminar a  execução. Vc poderia transcrever a minha qery anterior para o comando with.

     

    Grato,

     

    CREATE PROCEDURE SP_PREENCHE_FATO_CLIENTE

    as

    begin

    with CLIENTE as (

    SELECT CODCLI,NOMECLI,SEXOCLI

    FROM CRM.DBO.CLIENTES AS CLIENTES),

    ESCOLARIDADE AS(

    SELECT CODESC,NOMEESC

    FROM CRM.DBO.ESCOLARIDADES AS ESCOLARIDADE),

    ESTADOCIVIL AS (

    SELECT CODESTC,NOMEESTC

    FROM CRM.DBO.ESTADOSCIVIS AS ESTADOCIVIL),

    LOGRADOURO AS (

    select codCli,bairrocli,codCid,nomeCid,codEst,NomeEst

    from crm.dbo.clientes Cliente,

    crm.dbo.Cidades Cidades,

    crm.dbo.Estados Estado

    where Cliente.cidadeCli = Cidades.CodCid and cliente.EstadoCli=Estado.CodEst),

    PROMOCAO AS (

    SELECT CODCAM,NOMECAM,DTINICIOCAM,DTFIMCAM

    FROM CRM.DBO.CAMPANHAS AS PROMOCAO)

    INSERT INTO FATO_CLIENTE(ID_LOGRADOURO,

    ID_PROMOCAO,

    ID_ESCOLARIDADE,

    ID_ESTADO_CIVIL,

    ID_CLIENTE,QUANTIDADE)

    SELECT DIMENSAO_LOGRADOURO.ID_LOGRADOURO,

    DIMENSAO_ESCOLARIDADE.ID_ESCOLARIDADE,

    DIMENSAO_PROMOCAO.ID_PROMOCAO,

    DIMENSAO_ESTADO_CIVIL.ID_ESTADO_CIVIL,

    DIMENSAO_CLIENTE.ID_CLIENTE,

    1

    FROM LOGRADOURO,

    ESCOLARIDADE,PROMOCAO,ESTADOCIVIL,CLIENTE,

    DIMENSAO_ESCOLARIDADE,

    DIMENSAO_PROMOCAO,

    DIMENSAO_ESTADO_CIVIL,

    DIMENSAO_CLIENTE,

    DIMENSAO_LOGRADOURO

    WHERE (PROMOCAO.CODCAM = DIMENSAO_PROMOCAO.ID_PROMOCAO)

    AND (CLIENTE.CODCLI = DIMENSAO_CLIENTE.ID_CLIENTE)

    AND (ESCOLARIDADE.CODESC = DIMENSAO_ESCOLARIDADE.ID_ESCOLARIDADE)

    AND (ESTADOCIVIL.CODESTC = DIMENSAO_ESTADO_CIVIL.ID_ESTADO_CIVIL)

    AND (LOGRADOURO.CODCID = DIMENSAO_LOGRADOURO.ID_LOGRADOURO)

    END

     

    sexta-feira, 14 de novembro de 2008 17:25
  • Boa Tarde,

     

    Primeiro recomendo que você tire o prefixo sp_ do nome da sua SP. Toda vez que uma procedure tem o prefixo sp_ automaticamente ela será procurada primeiramente no banco MASTER para depois ser procurado no banco atual. Essa ida ao Master provoca um pequeno DELAY desnecessário.

     

    Quantos registros tem cada consulta utilizada no WITH ? As colunas ID possuem índices ?

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 14 de novembro de 2008 17:38
  • o meu banco tem no maximo 100 registros para cada consulta with.. a cada tabela usando with, tem a sua chave primaria..

     

    grato..

     

     

     

     

     

    sexta-feira, 14 de novembro de 2008 17:47
  • Olá Gildo,

     

    Se há 100 registros e cada um com sua chave primária essa consulta deveria ser muito rápida. Não há nenhum processo que esteja bloqueando você ? Não há nenhuma transação que tenha ficado aberta ? Não era para demorar

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 14 de novembro de 2008 20:05
  • Gustavo

     

    Boa noite

     

    Estou com essa query da minha tabela Fato e está me retornando 300 mil registros... essa query esta fazendo um plano cartesiano. 87 x 17 x 20 para cada  registro da tabela Promoção. Como resolver isso ? Agradeço

     

     

    use crm_dw
    CREATE PROCEDURE PREENCHE_FATO_CLIENTE
    as
    begin
    with CLIENTE as (
    SELECT CODCLI,NOMECLI,SEXOCLI
     FROM CRM.DBO.CLIENTES AS CLIENTES),
    ESCOLARIDADE AS(
    SELECT CODESC,NOMEESC
     FROM CRM.DBO.ESCOLARIDADES AS ESCOLARIDADE),
    ESTADOCIVIL AS (
     SELECT CODESTC,NOMEESTC
     FROM CRM.DBO.ESTADOSCIVIS AS ESTADOCIVIL),
    --LOGRADOURO AS (
     --select  codCli,bairrocli,codCid,nomeCid,codEst,NomeEst
    -- from crm.dbo.clientes Cliente,
    --  crm.dbo.Cidades Cidades,
    --  crm.dbo.Estados Estado),
    PROMOCAO AS (
     SELECT CODCAM,NOMECAM,DTINICIOCAM,DTFIMCAM
     FROM CRM.DBO.CAMPANHAS AS PROMOCAO)
    INSERT INTO FATO_CLIENTE(--ID_LOGRADOURO,
      ID_PROMOCAO,
         ID_ESCOLARIDADE,
      ID_ESTADO_CIVIL,
      ID_CLIENTE,QUANTIDADE)
    SELECT --DIMENSAO_LOGRADOURO.ID_LOGRADOURO,
     DIMENSAO_ESCOLARIDADE.ID_ESCOLARIDADE,
     DIMENSAO_PROMOCAO.ID_PROMOCAO,
     DIMENSAO_ESTADO_CIVIL.ID_ESTADO_CIVIL,
     DIMENSAO_CLIENTE.ID_CLIENTE,
     1
    FROM --LOGRADOURO,
        ESCOLARIDADE,PROMOCAO,ESTADOCIVIL,CLIENTE,
     DIMENSAO_ESCOLARIDADE,
     DIMENSAO_PROMOCAO,
     DIMENSAO_ESTADO_CIVIL,
     DIMENSAO_CLIENTE
     --DIMENSAO_LOGRADOURO
    WHERE (PROMOCAO.CODCAM = DIMENSAO_PROMOCAO.ID_PROMOCAO)
    AND (CLIENTE.CODCLI = DIMENSAO_CLIENTE.ID_CLIENTE)
    AND (ESCOLARIDADE.CODESC = DIMENSAO_ESCOLARIDADE.ID_ESCOLARIDADE)
    AND (ESTADOCIVIL.CODESTC = DIMENSAO_ESTADO_CIVIL.ID_ESTADO_CIVIL)
    --AND (LOGRADOURO.CODCID = DIMENSAO_LOGRADOURO.ID_LOGRADOURO)
    END

     

    sexta-feira, 21 de novembro de 2008 01:46
  • Bom Dia Gildo,

     

    Abandone a junção via WHERE e utilize INNER JOIN. O INNER JOIN lhe protegerá mais contra produtos cartesianos.

     

    [ ]s,

     

    Gustavo

    sexta-feira, 21 de novembro de 2008 11:37
  • bom dia

     

    Vc poderia me dar uma exemplo de com ficaria a minha query com INER Join ?

     

     

    Agradeço..

     

    sexta-feira, 21 de novembro de 2008 12:05
  • Olá Gildo,

     

    Segue uma pequena adaptação:

     

    Ao invés de:

     

    Code Snippet

    FROM ESCOLARIDADE, DIMENSAO_ESCOLARIDADE

    WHERE ESCOLARIDADE.CODESC = DIMENSAO_ESCOLARIDADE.ID_ESCOLARIDADE

     

    Use

     

    Code Snippet

    FROM ESCOLARIDADE

    INNER JOIN DIMENSAO_ESCOLARIDADE ON ESCOLARIDADE.CODESC = DIMENSAO_ESCOLARIDADE.ID_ESCOLARIDADE

     

    Quando se usa JOINs você é obrigado a especificar as condições através do operador ON. Quando se usa junção no WHERE, caso a condição seja esquecida a consulta irá rodar da mesma forma incorrendo em produtos cartesianos. Essa é mais uma razão para não utilizar junções em cláusula WHERE. Recomendo que você passe a utilizar JOINs ao invés da construção via cláusula WHERE.

     

    [ ]s,

     

    Gustavo

    sexta-feira, 21 de novembro de 2008 12:18
  •  

    Gustavo

     

    Esta apresenando esse erro:

    The objects "DIMENSAO_ESCOLARIDADE" and "DIMENSAO_ESCOLARIDADE" in the FROM clause have the same exposed names. Use correlation names to distinguish them

     

    quando coloco o INNER join..

     

     

    Grato,

    sexta-feira, 21 de novembro de 2008 15:10