Pergunta

Recebi uma tabela com cerca de 18.000 linhas.Cada registro descreve a localização de um cliente.O problema é que quando a pessoa criou a tabela, ela não adicionou um campo para “Nome da Empresa”, apenas “Nome do Local”, e uma empresa pode ter vários locais.

Por exemplo, aqui estão alguns registros que descrevem o mesmo cliente:

Tabela de Localização

 ID  Location_Name     
 1   TownShop#1        
 2   Town Shop - Loc 2 
 3   The Town Shop     
 4   TTS - Someplace   
 5   Town Shop,the 3   
 6   Toen Shop4        

Meu objetivo é fazer com que pareça:

Tabela de Localização

 ID  Company_ID   Location_Name     
 1   1            Town Shop#1       
 2   1            Town Shop - Loc 2 
 3   1            The Town Shop     
 4   1            TTS - Someplace   
 5   1            Town Shop,the 3   
 6   1            Toen Shop4        

Tabela da Empresa

 Company_ID  Company_Name  
 1           The Town Shop 

Não existe uma tabela "Empresa", terei que gerar a lista Nome da Empresa a partir do Nome do Local mais descritivo ou melhor que represente os vários locais.

Atualmente estou pensando que preciso gerar uma lista de nomes de locais semelhantes e, em seguida, examinar essa lista manualmente.

Qualquer sugestão sobre como posso abordar isso é apreciada.

@Neall, obrigado pela sua declaração, mas infelizmente cada nome de local é distinto, não há nomes de locais duplicados, apenas semelhantes.Portanto, nos resultados da sua declaração, "repcount" é 1 em cada linha.

@yukondude, sua etapa 4 é o cerne da minha pergunta.

Foi útil?

Solução

Atualize a pergunta. Você tem uma lista de CompanyNames disponível para você?Eu pergunto porque você talvez consiga usar o algoritmo Levenshtein para encontrar um relacionamento entre sua lista de CompanyNames e LocationNames.


Atualizar

Não há uma lista de nomes de empresas, terei que gerar o nome da empresa a partir do nome de local mais descritivo ou melhor que represente os vários locais.

OK...tente isto:

  1. Crie uma lista de CompanyNames candidatos encontrando LocationNames compostos em sua maioria ou todos os caracteres alfabéticos.Você pode usar expressões regulares por esta.Armazene esta lista em uma tabela separada.
  2. Classifique essa lista em ordem alfabética e (manualmente) determine quais entradas devem ser CompanyNames.
  3. Compare cada CompanyName com cada LocationName e obtenha uma pontuação de correspondência (use Levenshtein ou algum outro algoritmo de correspondência de string).Armazene o resultado em uma tabela separada.
  4. Defina uma pontuação limite de forma que qualquer MatchScore < Limite não seja considerado uma correspondência para um determinado CompanyName.
  5. Examine manualmente os nomes de localização por CompanyName | LocationName | Matchscore e descubra quais realmente correspondem.Encomendar por MatchScore deve tornar o processo menos doloroso.

Todo o propósito das ações acima é automatizar peças e limitar o escopo do seu problema.Está longe de ser perfeito, mas esperamos que você evite o trabalho de analisar registros de 18K manualmente.

Outras dicas

Eu tive que fazer isso antes.A única maneira real de fazer isso é combinar manualmente os vários locais.Use a interface do console do seu banco de dados e agrupe instruções select.Primeiro, adicione o campo “Nome da empresa”.Então:

SELECT count(*) AS repcount, "Location Name" FROM mytable
 WHERE "Company Name" IS NULL
 GROUP BY "Location Name"
 ORDER BY repcount DESC
 LIMIT 5;

Descubra a qual empresa pertence o local no topo da lista e atualize o campo do nome da sua empresa com um UPDATE ...WHERE "Nome do local" = instrução "O local".

P.S.- Você realmente deve dividir os nomes de suas empresas e locais em tabelas separadas e consultá-los por suas chaves primárias.

Atualizar:- Uau - não há duplicatas?Quantos registros você tem?

Eu recomendaria algum algoritmo complicado de correspondência de token, mas é realmente complicado de acertar e se seus dados não tiverem muita correlação (erros de digitação, etc), então não produzirão resultados muito bons.

Eu recomendo que você envie um trabalho para o Amazon Mecânico Turco e deixe um humano resolver isso.

Idealmente, você provavelmente desejaria uma tabela separada chamada Empresa e, em seguida, uma coluna company_id nesta tabela "Local" que seja uma chave estrangeira para a chave primária da tabela Empresa, provavelmente chamada de id.Isso evitaria uma boa duplicação de texto nesta tabela (mais de 18.000 linhas, uma chave estrangeira inteira economizaria bastante espaço em uma coluna varchar).

Mas você ainda se depara com um método para carregar a tabela Empresa e associá-la adequadamente às linhas em Local.Não há uma solução geral, mas você poderia fazer algo assim:

  1. Crie a tabela Empresa, com uma coluna id que incrementa automaticamente (depende do seu RDBMS).
  2. Encontre todos os nomes exclusivos de empresas e insira-os em Empresa.
  3. Adicione uma coluna, company_id, ao Location que aceita NULLs (por enquanto) e que seja uma chave estrangeira da coluna Company.id.
  4. Para cada linha em Local, determine a empresa correspondente e ATUALIZE a coluna company_id dessa linha com o ID dessa empresa.Esta é provavelmente a etapa mais desafiadora.Se seus dados forem como os mostrados no exemplo, você provavelmente terá que fazer muitas execuções com várias abordagens de correspondência de strings.
  5. Depois que todas as linhas em Location tiverem um valor company_id, você poderá ALTER a tabela Company para adicionar uma restrição NOT NULL à coluna company_id (assumindo que cada location deve ter uma empresa, o que parece razoável).

Se você puder fazer uma cópia de sua tabela Location, poderá criar gradualmente uma série de instruções SQL para preencher a chave estrangeira company_id.Se você cometer um erro, basta recomeçar e executar novamente o script até o ponto de falha.

Sim, a etapa 4 do meu post anterior é confusa.

Não importa o que aconteça, você provavelmente terá que fazer parte disso manualmente, mas poderá automatizar a maior parte.Para os locais de exemplo que você forneceu, uma consulta como a seguinte definiria o valor company_id apropriado:

UPDATE  Location
SET     Company_ID = 1
WHERE   (LOWER(Location_Name) LIKE '%to_n shop%'
OR      LOWER(Location_Name) LIKE '%tts%')
AND     Company_ID IS NULL;

Acredito que isso corresponderia aos seus exemplos (adicionei o IS NULL parte para não substituir os valores Company_ID definidos anteriormente), mas é claro que em 18.000 linhas você terá que ser bastante criativo para lidar com as várias combinações.

Outra coisa que pode ajudar seria usar os nomes da Empresa para gerar consultas como a acima.Você poderia fazer algo como o seguinte (no MySQL):

SELECT  CONCAT('UPDATE Location SET Company_ID = ',
        Company_ID, ' WHERE LOWER(Location_Name) LIKE ',
        LOWER(REPLACE(Company_Name), ' ', '%'), ' AND Company_ID IS NULL;')
FROM    Company;

Em seguida, basta executar as instruções que ele produz.Isso poderia fazer muito trabalho grunge para você.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top