Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Comparando linhas na tabela para diferenças entre campos


Qualquer expressão em SQL deve fazer referência a colunas apenas em uma linha (exceto subconsultas).

Um JOIN pode ser usado para fazer duas linhas diferentes em uma linha do conjunto de resultados.

Assim, você pode comparar valores em linhas diferentes fazendo uma autojunção. Aqui está um exemplo que mostra a junção de cada linha a todas as outras linhas associadas ao mesmo cliente (excluindo uma junção de uma linha para si mesma):
SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)

Agora você pode escrever expressões que comparam colunas. Por exemplo, para restringir a consulta acima àquelas em que field1 é diferente:
SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)
WHERE c1.field1 <> c2.field1;

Você não especifica que tipos de comparações você precisa fazer, então vou deixar isso para você. O ponto-chave é que, em geral, você pode usar uma autojunção para comparar linhas em uma determinada tabela.

Re seus comentários e esclarecimentos:Ok, então sua "diferença" não é simplesmente pelo valor, mas pela posição ordinal da linha. Lembre-se que bancos de dados relacionais não possuem um conceito de número de linha, eles apenas possuem ordem de linhas em relação a alguma ordem que você deve especificar em um ORDER BY cláusula. Não confunda o "id " pseudochave com número de linha, os números são atribuídos como monotonicamente crescentes apenas por coincidência de sua implementação.

No MySQL, você pode aproveitar as variáveis ​​definidas pelo usuário para alcançar o efeito que você está procurando. Ordene a consulta por clientId e depois por id e rastreie valores por coluna nas variáveis ​​de usuário do MySQL. Quando o valor em uma linha atual for diferente do valor na variável, faça o realce que você ia fazer. Vou mostrar um exemplo para um campo:
SET @clientid = -1, @field1 = '';
SELECT id, clientId, field1, @clientid, @field1,
  IF(@clientid <> clientid, 
    ((@clientid := clientid) AND (@field1 := field1)) = NULL,
    IF (@field1 <> field1, 
      (@field1 := field1), 
      NULL
    )
  ) AS field1_changed
FROM client c
ORDER BY clientId, id;

Observe que esta solução não é realmente diferente de apenas selecionar todas as linhas com SQL simples e rastrear os valores com variáveis ​​de aplicativo à medida que você busca linhas.