कम ईमानदारी वाले एक तालिका को सामान्यीकृत करना

मुझे लगभग 18000 पंक्तियों के साथ एक टेबल सौंप दिया गया है। प्रत्येक रिकॉर्ड एक ग्राहक के स्थान का वर्णन करता है। मुद्दा यह है कि जब व्यक्ति ने टेबल बनाया, तो उन्होंने "कंपनी नाम" के लिए कोई फ़ील्ड नहीं जोड़ा, केवल "स्थान का नाम" और एक कंपनी के पास कई स्थान हो सकते हैं।

उदाहरण के लिए, यहां कुछ रिकॉर्ड हैं जो एक ही ग्राहक का वर्णन करते हैं:

स्थान तालिका

 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        

मेरा लक्ष्य यह दिखाना है:

स्थान तालिका

 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        

कंपनी तालिका

 Company_ID  Company_Name  
 1           The Town Shop 

कोई "कंपनी" टेबल नहीं है, मुझे कंपनी के नाम सूची को सबसे वर्णनात्मक या सर्वोत्तम स्थान नाम से उत्पन्न करना होगा जो एकाधिक स्थानों का प्रतिनिधित्व करता है।

वर्तमान में मैं सोच रहा हूं कि मुझे स्थान नामों की एक सूची उत्पन्न करने की आवश्यकता है जो समान हैं, और फिर उस सूची के माध्यम से हाथ से जाएं।

मैं इस पर कैसे पहुंच सकता हूं इस पर कोई सुझाव सराहना की जाती है।

@Neall, आपके कथन के लिए धन्यवाद, लेकिन दुर्भाग्य से, प्रत्येक स्थान का नाम अलग है, कोई डुप्लिकेट स्थान नाम नहीं है, केवल समान है। तो आपके कथन के परिणामों में "repcount" प्रत्येक पंक्ति में 1 है।

@Yukondude, आपका चरण 4 मेरे प्रश्न का दिल है।

0
ro fr bn

5 उत्तर

कृपया प्रश्न अपडेट करें, क्या आपके पास उपलब्ध कंपनी नामों की एक सूची है? मैं पूछता हूं क्योंकि आप कंपनी नामों और स्थान नामों की अपनी सूची के बीच संबंध खोजने के लिए लेवेनशेटिन अलगो का उपयोग करने में सक्षम हो सकते हैं।


अपडेट

कंपनी के नामों की एक सूची नहीं है, मुझे कंपनी के नाम को सबसे वर्णनात्मक या सर्वोत्तम स्थान नाम से उत्पन्न करना होगा जो एकाधिक स्थानों का प्रतिनिधित्व करता है।

ठीक है ... इसे आजमाएं:

  1. Build a list of candidate CompanyNames by finding LocationNames made up of mostly or all alphabetic characters. You can use regular expressions for this. Store this list in a separate table.
  2. Sort that list alphabetically and (manually) determine which entries should be CompanyNames.
  3. Compare each CompanyName to each LocationName and come up with a match score (use Levenshtein or some other string matching algo). Store the result in a separate table.
  4. Set a threshold score such that any MatchScore < Threshold will not be considered a match for a given CompanyName.
  5. Manually vet through the LocationNames by CompanyName | LocationName | MatchScore, and figure out which ones actually match. Ordering by MatchScore should make the process less painful.

उपरोक्त कार्यों का पूरा उद्देश्य भागों को स्वचालित करना और आपकी समस्या के दायरे को सीमित करना है। यह बिल्कुल सही नहीं है, लेकिन आशा है कि आप हाथ से 18 के रिकॉर्ड के माध्यम से जाने की परेशानी बचाएंगे।

0
जोड़ा

आदर्श रूप से, आप संभवतः कंपनी नामक एक अलग तालिका चाहते हैं और फिर इस "स्थान" तालिका में एक कंपनी_आईडी कॉलम चाहते हैं जो कि कंपनी टेबल की प्राथमिक कुंजी के लिए एक विदेशी कुंजी है, जिसे संभवतः आईडी कहा जाता है। यह इस तालिका में टेक्स्ट डुप्लिकेशंस के एक उचित बिट से बच जाएगा (18,000 से अधिक पंक्तियां, एक पूर्णांक विदेशी कुंजी एक वर्चर कॉलम पर काफी जगह बचाएगी)।

लेकिन आप अभी भी उस कंपनी तालिका को लोड करने के लिए एक विधि का सामना कर रहे हैं और फिर इसे स्थान में पंक्तियों के साथ सही तरीके से जोड़ रहे हैं। कोई सामान्य समाधान नहीं है, लेकिन आप इन पंक्तियों के साथ कुछ कर सकते हैं:

  1. एक आईडी कॉलम के साथ कंपनी तालिका बनाएं, जो स्वतः-वृद्धि (आपके आरडीबीएमएस पर निर्भर करता है)।
  2. सभी अद्वितीय कंपनी के नाम खोजें और उन्हें कंपनी में डालें।
  3. उस कॉलम, company_id को उस स्थान पर जोड़ें जो NULL स्वीकार करता है (अभी के लिए) और यह कंपनी.आईडी कॉलम की एक विदेशी कुंजी है।
  4. स्थान में प्रत्येक पंक्ति के लिए, संबंधित कंपनी निर्धारित करें, और उस कंपनी की आईडी के साथ उस पंक्ति का company_id कॉलम अपडेट करें। यह सबसे चुनौतीपूर्ण कदम है। यदि आपका डेटा उदाहरण में जो दिखाता है, वैसा ही है, तो आपको विभिन्न स्ट्रिंग मिलान दृष्टिकोणों के साथ इस पर कई रन लेना होगा।
  5. एक बार स्थान पर सभी पंक्तियों में एक कंपनी_आईडी मान होता है, तो आप कंपनी तालिका को कंपनी_आईडी कॉलम में नॉट नल बाधा जोड़ने के लिए बदल सकते हैं (यह मानते हुए कि प्रत्येक स्थान होना चाहिए एक कंपनी है, जो उचित लगता है )।

यदि आप अपनी स्थान तालिका की प्रतिलिपि बना सकते हैं, तो आप कंपनी_आईडी विदेशी कुंजी को पॉप्युलेट करने के लिए धीरे-धीरे SQL कथन की श्रृंखला बना सकते हैं। यदि आप कोई गलती करते हैं, तो आप विफलता के बिंदु पर स्क्रिप्ट को फिर से शुरू कर सकते हैं और फिर से शुरू कर सकते हैं।

0
जोड़ा

हां, मेरी पिछली पोस्ट से वह चरण 4 एक डोज़ी है।

कोई फर्क नहीं पड़ता कि, आपको शायद इसे हाथ से कुछ करना होगा, लेकिन आप इसे थोक करने में सक्षम हो सकते हैं। आपके द्वारा दिए गए उदाहरण स्थानों के लिए, निम्न की तरह एक क्वेरी उपयुक्त company_id मान निर्धारित करेगी:

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;

मेरा मानना ​​है कि आपके उदाहरणों से मेल खाएगा (मैंने पहले से सेट कंपनी_आईडी मानों को ओवरराइट करने के लिए IS NULL भाग जोड़ा है), लेकिन निश्चित रूप से 18,000 पंक्तियों में आपको विभिन्न को संभालने के लिए बहुत आविष्कारक होना होगा संयोजन।

कुछ और जो मदद कर सकता है, उपर्युक्त प्रश्नों को उत्पन्न करने के लिए कंपनी में नामों का उपयोग करना होगा। आप निम्न की तरह कुछ कर सकते हैं (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;

फिर बस उस बयान को चलाएं जो इसे उत्पन्न करता है। यह आपके लिए बहुत सारे ग्रंज काम कर सकता है।

0
जोड़ा

मैं कुछ जटिल टोकन मिलान एल्गोरिदम की सिफारिश करने जा रहा था लेकिन सही होने के लिए यह वास्तव में मुश्किल है और यदि आपके पास डेटा में बहुत सहसंबंध नहीं है (टाइपो, आदि) तो यह बहुत अच्छे नतीजे नहीं देगा।

मैं आपको अमेज़ॅन मैकेनिकल तुर्क पर नौकरी सबमिट करने की सलाह दूंगा और मानव को इसे हल करने दें।

0
जोड़ा

मुझे पहले ऐसा करना पड़ा। ऐसा करने का एकमात्र असली तरीका है विभिन्न स्थानों को मैन्युअल रूप से मिलान करना। अपने डेटाबेस के कंसोल इंटरफ़ेस का उपयोग करें और चयन कथन समूहबद्ध करें। सबसे पहले, अपना "कंपनी का नाम" फ़ील्ड जोड़ें। फिर:

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

सूची के शीर्ष पर स्थित स्थान कौन सी कंपनी का पता लगाएं और फिर अपनी कंपनी का नाम फ़ील्ड अपडेट के साथ अपडेट करें ... जहां "स्थान का नाम" = "स्थान" कथन है।

अनुलेख - आपको वास्तव में अलग-अलग तालिकाओं में अपनी कंपनी के नाम और स्थान नामों को तोड़ना चाहिए और उन्हें उनकी प्राथमिक कुंजी से संदर्भित करना चाहिए।

अद्यतन: - वाह - कोई डुप्लीकेट नहीं? आपके पास कितने रिकॉर्ड हैं?

0
जोड़ा