AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 16711
Accepted
Ben Brocka
Ben Brocka
Asked: 2012-04-19 10:25:01 +0800 CST2012-04-19 10:25:01 +0800 CST 2012-04-19 10:25:01 +0800 CST

Identificando linhas que não correspondem a uma linha mestre

  • 772

Estou comparando um monte de tabelas de diferentes bancos de dados em diferentes servidores para um registro mestre. Preciso saber quais servidores, identificados por locationID, possuem as linhas não correspondentes porque podem precisar de manutenção.

Eu tenho uma EXCEPTconsulta simples onde comparo uma tabela onde cada linha é a configuração de cada servidor; table1tem uma linha por servidor com todas as configurações mais locationIDque é uma coluna que me diz qual servidor é. Eu comparo tudo isso com uma table1_mastertabela que tem as configurações corretas, mas excluo o locationIDporque não corresponderá.

Consulta simples abaixo:

SELECT everything, but, locationID
FROM table1
EXCEPT
SELECT everything, but, locationID
FROM table1_master

Há apenas uma linha mestre com a qual comparo todos os servidores e não a seleciono locationIDaqui.

Este é um exemplo das linhas que estou comparando. Cada um tem uma chave primária, uma única coluna varchare uma lista gigante com dezenas de colunas. Desejo comparar todas as colunas , exceto LocationID, mas preciso de LocationID para identificar as linhas.

LocationID             setting    setting    setting     setting
CS02      C            Y           Y         Y           Y
CS03      C            Y           Y         Y           Y
CS06      C            Y           N         Y           Y

Neste exemplo, digamos que CS02 é meu registro mestre, então, como todas as configurações são as mesmas em CS02 e CS03, essas linhas não aparecem, mas CS06 sim. Mas em minha EXCEPTconsulta, não estou capturando LocationID, então não sei qual linha foi retornada.

Isso retorna as linhas de que preciso, mas NÃO o locationID, então não sei quais linhas estão erradas. Existe alguma maneira de incluir locationIDno conjunto de resultados enquanto excluo as linhas correspondentes?

A solução que pensei foi fazer uma linha para cada servidor da table1_mastertabela, assim cada um locationIDfica representado, mas todos tem os mesmos dados fora isso. Minha EXCLUDEconsulta deve retornar locationIDe minhas informações, mas essa é a melhor maneira de fazer isso?

sql-server sql-server-2005
  • 3 3 respostas
  • 1463 Views

3 respostas

  • Voted
  1. Best Answer
    Aaron Bertrand
    2012-04-19T11:36:53+08:002012-04-19T11:36:53+08:00

    Você também pode fazer isso com SQL dinâmico sem precisar criar manualmente todos os nomes de coluna.

    DECLARE @sql NVARCHAR(MAX), @c1 NVARCHAR(MAX), @c2 NVARCHAR(MAX);
    
    SELECT @c1 = N'', @c2 = N'';
    
    SELECT 
      @c1 = @c1 + ',' + QUOTENAME(name),
      @c2 = @c2 + ' AND m.' + QUOTENAME(name) + ' = s.' + QUOTENAME(name)
     FROM sys.columns
     WHERE name <> 'LocationID'
     AND [object_id] = OBJECT_ID('dbo.table1');
    
    SET @sql = ';WITH s AS (
           SELECT ' + STUFF(@c1, 1, 1, '') + ' FROM dbo.table1
           EXCEPT 
           SELECT ' + STUFF(@c1, 1, 1, '') + ' FROM dbo.table1_master
         ) 
         SELECT m.LocationID
     FROM s INNER JOIN dbo.table1 AS m ON 1 = 1
     ' + @c2;
    
    SELECT @sql;
    --EXEC sp_executesql @sql;
    

    Você pode pegar a saída desta consulta como está e armazená-la em algum lugar, ou pode comentar SELECTe descomentar EXECe deixá-la como SQL dinâmico permanente - neste caso, ela se adaptará automaticamente às alterações de coluna nas duas tabelas.

    Outra ideia (assumindo que LocationID é único) - e me ocorreu que você pode querer incluir a linha mestre para que possa identificar rapidamente as colunas que são diferentes:

      ;WITH c AS 
      (
        SELECT t.LocationID, m.setting1, m.setting2, ...
          FROM dbo.table1 AS t CROSS JOIN dbo.table1_master AS m
      )
      SELECT DISTINCT src = '> master', setting1, setting2, ...
        FROM c
      UNION ALL
      (
        SELECT RTRIM(LocationID), setting1, setting2, ...
          FROM dbo.table1
        EXCEPT
        SELECT RTRIM(LocationID), setting1, setting2, ...
          FROM c
      )
      ORDER BY src;
    

    Esta versão é um pouco mais barata (principalmente evitando a DISTINCTcomparação com a tabela mestre, ao custo de precisar especificar todas as colunas mais uma vez - o que novamente você pode automatizar conforme acima):

      ;WITH m AS 
      (
        SELECT setting1, setting2, ... 
          FROM dbo.table1_master
      ),
      c AS 
      (
        SELECT src = RTRIM(t.LocationID), m.setting1, m.setting2, ...
          FROM dbo.table1 AS t CROSS JOIN m
      )
      SELECT src = '> master', setting1, setting2, ...
        FROM m
      UNION ALL
      (
        SELECT RTRIM(LocationID), setting1, setting2, ...
          FROM dbo.table1
        EXCEPT
        SELECT src, setting1, setting2, ...
          FROM c
      )
      ORDER BY src;
    

    No entanto, todas essas opções são de desempenho inferior com planos piores do que o simples de Rachel LEFT JOIN. Tentei me ater ao tema do uso EXCEPT, embora seja mais uma questão de sintaxe do que de desempenho.

    A principal conclusão é que, se a contagem de colunas for muito alta para lidar manualmente, você pode usar a abordagem SQL dinâmica acima para construir qualquer consulta que deseja usar - e você pode fazer isso uma vez e armazenar o resultado ou ter o código gerado todas as vezes. Para gerar a consulta de Rachel usando SQL dinâmico, não precisa mudar muito:

    DECLARE @sql NVARCHAR(MAX), @and NVARCHAR(MAX), @anycol NVARCHAR(128);
    SELECT @sql = N'', @and = N'';
    
    SELECT @and = @and + ' AND t.' + QUOTENAME(name) + ' = m.' + QUOTENAME(name)
      FROM sys.columns
      WHERE [object_id] = OBJECT_ID('dbo.table1_master');
    
    SELECT TOP (1) @anycol = QUOTENAME(name)
      FROM sys.columns
      WHERE [object_id] = OBJECT_ID('dbo.table1_master')
      ORDER BY name;
    
    SET @sql = 'SELECT locationID
    FROM dbo.table1 AS t
    LEFT OUTER JOIN dbo.table1_master AS m ON 1 = 1' 
      + @and + ' WHERE m.' + @anycol + ' IS NULL;';
    
    SELECT @sql;
    --EXEC sp_executesql @sql;
    
    • 4
  2. JNK
    2012-04-19T11:26:10+08:002012-04-19T11:26:10+08:00

    Eu recomendaria:

    • Criar um Hashcampo que é uma coluna computada persistente com uma definição ao longo das linhas deHASHBYTES('SHA1', Field1 + Field2 + Field3...)
    • Comparando apenas esse HASHvalor do seu "mestre" com seus outros registros
    • Exibindo todos os valores reais de linhas não correspondentes

    Algo como

    SELECT *
    FROM Table1
    WHERE HashField <> (SELECT Hashfield FROM Table1_Master)
    
    • 1
  3. Rachel
    2012-04-19T11:26:27+08:002012-04-19T11:26:27+08:00

    O que há de errado em apenas unir as duas tabelas em cada coluna (ou usar uma instrução where) e selecionar itens que não existem na segunda tabela?

    SELECT locationID
    FROM table1
    LEFT OUTER JOIN table1_master 
        ON table1.a = table1_master.a
        AND table1.b = table1_master.b
        AND table1.c = table1_master.c
    WHERE table1_master.a is null
    

    Pode não ser bonito, mas deve funcionar

    • 1

relate perguntas

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

  • Downgrade do SQL Server 2008 para 2005

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve