sql-server - SQL सर्वर में डुप्लिकेट रिकॉर्ड का संयोजन




sql-server-2012 (3)

दो चरण: 1. सही स्थानों के साथ रिकॉर्ड अपडेट करें, 2. गलत स्थानों के साथ रिकॉर्ड हटाएं।

update mytable
set onhand = onhand + 
(
  select coalesce(sum(wrong.onhand), 0)
  from mytable wrong
  where wrong.location like ' %'
  and trim(wrong.location) = mytable.location
)
where location not like ' %';

delete from mytable where location like ' %';

मेरे पास SQL ​​Server 2012 में एक मेज है जिसमें भाग की एक सूची, भागों का स्थान और हाथ की मात्रा मौजूद है मेरे पास समस्या यह है कि कोई व्यक्ति उस स्थान के सामने एक स्थान रखता है जब उन्होंने उसे डाटाबेस में जोड़ा। इसने दो रिकॉर्ड होने की अनुमति दी।

मुझे एक ऐसी नौकरी बनाने की ज़रूरत है जो स्थान से पहले रिक्त स्थान वाले भागों को खोज लेगा और उन हिस्सों को स्थान के सामने बिना रिक्त स्थान के समान भागों में जोड़ देगा। मुझे पूरा यकीन नहीं है कि इस के साथ भी कहां शुरू करना चाहिए।

यह पहले है:

  Partno  |  PartRev  |  Location  |  OnHand  |  Identity_Column
--------------------------------------------------------------------
  0D6591D    000          MV3         55.000     103939
  0D6591D    000         MV3          -55.000    104618

काम चलने के बाद मैं यह करना चाहता हूं:

  Partno  |  PartRev  |  Location  |  OnHand  |  Identity_Column
--------------------------------------------------------------------
  0D6591D    000         MV3         0           104618

अभिलेखों की पहचान करने के लिए आप कुछ समूह के साथ होविंग क्लॉज कर सकते हैं। मैंने स्थान कॉलम में रिक्त स्ट्रिंग के साथ रिक्त स्थान को बदलने के लिए जगह का उपयोग किया है, आप LTRIM और RTRIM उपयोग भी कर सकते हैं:

CREATE TABLE #Sample
    (
      [Partno] VARCHAR(7) ,
      [PartRev] INT ,
      [Location] VARCHAR(5) ,
      [OnHand] INT ,
      [Identity_Column] INT
    );


INSERT INTO #Sample
    ([Partno], [PartRev], [Location], [OnHand], [Identity_Column])
VALUES
    ('0D6591D', 000, ' MV3', 55.000, 103939),
    ('0D6591D', 000, 'MV3', -55.000, 104618)
;

SELECT Partno ,
       PartRev ,
       REPLACE( Location, ' ', '') Location,
       SUM(OnHand) [OnHand]
FROM #Sample
GROUP BY REPLACE(Location, ' ', '') ,
         Partno ,
         PartRev
HAVING COUNT(Identity_Column) > 1;

DROP TABLE #Sample;

पैदा करता है:

Partno  PartRev Location    OnHand
0D6591D 0       MV3         0

इसमें बहुत सारे जवाब हैं, लेकिन मुझे इस विस्तारित विधि को जोड़ने की आवश्यकता महसूस होती है। यह बहुत लंबा लगता है, लेकिन यह बेहद उपयोगी है यदि आप एक सक्रिय डेटाबेस में लाखों पंक्तियों वाली तालिका में एक न्यूल फ़ील्ड जोड़ रहे हैं।

ALTER TABLE {schemaName}.{tableName}
    ADD {columnName} {datatype} NULL
    CONSTRAINT {constraintName} DEFAULT {DefaultValue}

UPDATE {schemaName}.{tableName}
    SET {columnName} = {DefaultValue}
    WHERE {columName} IS NULL

ALTER TABLE {schemaName}.{tableName}
    ALTER COLUMN {columnName} {datatype} NOT NULL

यह क्या करेगा, कॉलम को एक शून्य क्षेत्र के रूप में जोड़ें और डिफ़ॉल्ट मान के साथ, सभी फ़ील्ड्स को डिफ़ॉल्ट मान पर अपडेट करें (या आप अधिक सार्थक मान असाइन कर सकते हैं), और आखिरकार यह कॉलम को नल में बदल देगा।

इसका कारण यह है कि यदि आप एक बड़े पैमाने पर तालिका को अपडेट करते हैं और एक नया नल फ़ील्ड जोड़ते हैं तो उसे प्रत्येक पंक्ति में लिखना होगा और इस प्रकार संपूर्ण तालिका को लॉक कर देगा क्योंकि यह कॉलम जोड़ता है और फिर सभी मान लिखता है।

यह विधि उस सुस्त कॉलम को जोड़ती है जो अपने आप से बहुत तेज़ी से संचालित होती है, फिर शून्य स्थिति को सेट करने से पहले डेटा भरती है।

मैंने पाया है कि एक ही बयान में पूरी चीज करने से 4-8 मिनट के लिए हमारी अधिक सक्रिय टेबलों में से एक लॉक हो जाएगा और अक्सर मैंने प्रक्रिया को मार दिया है। यह विधि प्रत्येक भाग में आमतौर पर केवल कुछ सेकंड लगते हैं और न्यूनतम लॉकिंग का कारण बनता है।

इसके अतिरिक्त, यदि आपके पास अरबों पंक्तियों के क्षेत्र में एक टेबल है तो यह अपडेट को बैच करने के लायक हो सकता है:

WHILE 1=1
BEGIN
    UPDATE TOP (1000000) {schemaName}.{tableName}
        SET {columnName} = {DefaultValue}
        WHERE {columName} IS NULL

    IF @@ROWCOUNT < 1000000
        BREAK;
END






sql sql-server sql-server-2012