Domanda

Mi è stata consegnata una tabella con circa 18000 righe.Ogni record descrive la posizione di un cliente.Il problema è che quando la persona ha creato la tabella, non ha aggiunto un campo per "Nome azienda", solo "Nome posizione" e una società può avere molte sedi.

Ad esempio, ecco alcuni record che descrivono lo stesso cliente:

Tabella delle posizioni

 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        

Il mio obiettivo è farlo sembrare:

Tabella delle posizioni

 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        

Tavolo aziendale

 Company_ID  Company_Name  
 1           The Town Shop 

Non esiste una tabella "Azienda", dovrò generare l'elenco dei nomi dell'azienda dal nome della località più descrittivo o migliore che rappresenta le molteplici località.

Attualmente sto pensando di dover generare un elenco di nomi di località simili e quindi esaminare manualmente l'elenco.

Qualsiasi suggerimento su come posso affrontare questo problema è apprezzato.

@Neall, grazie per la tua affermazione, ma sfortunatamente ogni nome di località è distinto, non ci sono nomi di località duplicati, solo simili.Quindi nei risultati della tua affermazione "repcount" è 1 in ogni riga.

@yukondude, il tuo passaggio 4 è il cuore della mia domanda.

È stato utile?

Soluzione

Aggiorna la domanda, hai un elenco di CompanyNames a tua disposizione?Lo chiedo perché forse potresti utilizzare l'algoritmo Levenshtein per trovare una relazione tra il tuo elenco di CompanyNames e LocationNames.


Aggiornamento

Non esiste un elenco di nomi di società, dovrò generare il nome della società dal nome della posizione più descrittivo o migliore che rappresenta le molteplici sedi.

Va bene...prova questo:

  1. Crea un elenco di CompanyNames candidati trovando LocationNames composti principalmente o tutti da caratteri alfabetici.Puoi usare espressioni regolari per questo.Memorizza questo elenco in una tabella separata.
  2. Ordina l'elenco in ordine alfabetico e determina (manualmente) quali voci dovrebbero essere CompanyNames.
  3. Confronta ciascun CompanyName con ciascun LocationName e ottieni un punteggio di corrispondenza (usa Levenstein o qualche altro algoritmo di corrispondenza delle stringhe).Memorizza il risultato in una tabella separata.
  4. Imposta un punteggio soglia in modo tale che qualsiasi MatchScore < Threshold non venga considerato una corrispondenza per un determinato CompanyName.
  5. Vet manualmente tramite il posto di localizzazione di CompanyName | Locationname | Matchscore e capire quali si abbinano effettivamente.Ordinare tramite MatchScore dovrebbe rendere il processo meno doloroso.

Lo scopo delle azioni di cui sopra è automatizzare le parti e limitare la portata del problema.È tutt'altro che perfetto, ma si spera ti risparmierà la fatica di esaminare manualmente i record da 18K.

Altri suggerimenti

Ho già dovuto farlo prima.L'unico vero modo per farlo è abbinare manualmente le varie posizioni.Utilizza l'interfaccia della console del tuo database e raggruppa le istruzioni select.Innanzitutto, aggiungi il campo "Nome azienda".Poi:

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

Scopri a quale azienda appartiene la posizione in cima all'elenco e quindi aggiorna il campo del nome della tua azienda con un AGGIORNAMENTO...WHERE "Nome della posizione" = istruzione "La posizione".

PS- Dovresti davvero suddividere i nomi delle aziende e dei luoghi in tabelle separate e fare riferimento ad essi tramite le relative chiavi primarie.

Aggiornamento:- Wow, nessun duplicato?Quanti record hai?

Stavo per consigliare un complicato algoritmo di corrispondenza dei token, ma è davvero difficile da ottenere correttamente e se i dati non hanno molta correlazione (errori di battitura, ecc.), non darà risultati molto buoni.

Ti consiglierei di inviare un lavoro a Turco meccanico di Amazon e lasciare che un essere umano risolva la questione.

Idealmente, probabilmente vorresti una tabella separata denominata Company e poi una colonna company_id in questa tabella "Location" che sia una chiave esterna per la chiave primaria della tabella Company, probabilmente chiamata id.Ciò eviterebbe un bel po' di duplicazione del testo in questa tabella (oltre 18.000 righe, una chiave esterna intera risparmierebbe un bel po' di spazio su una colonna varchar).

Ma devi ancora affrontare un metodo per caricare la tabella Company e quindi associarla correttamente alle righe in Location.Non esiste una soluzione generale, ma potresti fare qualcosa in questo senso:

  1. Crea la tabella Company, con una colonna id che si incrementa automaticamente (dipende dal tuo RDBMS).
  2. Trova tutti i nomi di società univoci e inseriscili in Azienda.
  3. Aggiungi una colonna, company_id, a Location che accetta NULL (per ora) e che è una chiave esterna della colonna Company.id.
  4. Per ogni riga in Posizione, determina l'azienda corrispondente e AGGIORNA la colonna company_id di quella riga con l'ID di quell'azienda.Questo è probabilmente il passo più impegnativo.Se i tuoi dati sono come quelli mostrati nell'esempio, probabilmente dovrai eseguire molte prove con vari approcci di corrispondenza delle stringhe.
  5. Una volta che tutte le righe in Location hanno un valore company_id, puoi ALTERare la tabella Company per aggiungere un vincolo NOT NULL alla colonna company_id (assumendo che ogni location dovere avere una compagnia, il che sembra ragionevole).

Se riesci a creare una copia della tabella Location, puoi creare gradualmente una serie di istruzioni SQL per popolare la chiave esterna company_id.Se commetti un errore, puoi semplicemente ricominciare da capo ed eseguire nuovamente lo script fino al punto di fallimento.

Sì, il passaggio 4 del mio post precedente è una cosa stupida.

Non importa cosa, probabilmente dovrai fare una parte di questo a mano, ma potresti essere in grado di automatizzare la maggior parte.Per le sedi di esempio fornite, una query come la seguente imposterebbe il valore company_id appropriato:

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;

Credo che corrisponderebbe ai tuoi esempi (ho aggiunto il IS NULL parte per non sovrascrivere i valori Company_ID precedentemente impostati), ma ovviamente su 18.000 righe dovrai essere piuttosto inventivo per gestire le varie combinazioni.

Qualcos'altro che potrebbe essere d'aiuto sarebbe utilizzare i nomi in Company per generare query come quella sopra.Potresti fare qualcosa di simile (in 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;

Quindi esegui semplicemente le istruzioni che produce.Questo potrebbe fare gran parte del lavoro grunge per te.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top