2009-11-17 30 views
6

मुझे केवल तालिका से डुप्लिकेट पंक्तियां हटाने की आवश्यकता है, जैसे कि मेरे पास तालिका में 3 डुप्लिकेट पंक्तियां हैं, मेरी क्वेरी 3 डुप्लिकेट पंक्तियों से 2 पंक्तियां हटा देगी।तालिका से डुप्लिकेट रिकॉर्ड हटाना - SQL क्वेरी

मैं इसे कैसे प्राप्त कर सकता हूं? क्रिप्या मेरि सहायता करे।

+0

@Matt - मैंने देखा कि तुम वहाँ क्या किया :) – jensgram

+0

हे, मुझे लगता है कि यह व्याख्या के लिए खुला है, लेकिन पहला वाक्य अनिवार्य है, तो .. :) – Matt

+0

यह एक साक्षात्कार प्रश्न की तरह लगता है। कौन सा डीबी, वहाँ आईडी हैं। क्या आप temp टेबल का उपयोग करने की अनुमति है? –

उत्तर

12

नीचे दिए गए क्वेरी करने का प्रयास करें, यह निश्चित रूप से पूरा करेगा अपने उद्देश्य

SET ROWCOUNT 1 
DELETE test 
FROM test a 
WHERE (SELECT COUNT(*) FROM test b WHERE b.name = a.name) > 1 
WHILE @@rowcount > 0 
    DELETE test 
    FROM test a 
    WHERE (SELECT COUNT(*) FROM test b WHERE b.name = a.name) > 1 
SET ROWCOUNT 0 

जहां परीक्षण अपनी मेज नाम

+2

@ मुहम्मद - आप सही हैं। मैंने उस प्रभाव के डोर के जवाब में भी एक टिप्पणी छोड़ दी। यह सही जवाब है क्योंकि यह संतानु के प्रश्न में कुछ भी "अतिरिक्त" नहीं मानता है। मैं इस जवाब के साथ खेल रहा हूं और मुझे यह मानना ​​है कि मेरे पास केवल एक चमक है कि यह क्यों काम करता है। यह ROWCOUNT और WHILE का उपयोग इस तरीके से करता है कि मैं अभी तक काफी समझ में नहीं आता हूं। कुछ नया सीखना हमेशा अच्छा है! ... और मैं आम तौर पर एक है जो –

+1

मार्क :-(एसक्यूएल प्रश्न पर असंभव जवाब हो जाता हूँ, मैं आपको एक जवाब के रूप में पोस्ट करना चाहिए तो मैं यह वोट दें कर सकते हैं लगता है – Zoidberg

+2

ठीक है - मैं जबकि अब मिल - यह नहीं हटाएं (जादुई रूप से) को हटाएं। सेट ROWCOUNT 1 यह सुनिश्चित करता है कि निम्नलिखित ऑपरेशन केवल एक समय पर पूरी तरह से सेट उन्मुख होने के बजाय 1 ROW पर लागू हों। हटाएं फिर एक पंक्ति को हटा दें जहां a.name पर डुप्लिकेट है WHILE परिणामी @@ rowcount का उपयोग करता है और एक लूप शुरू करता है। जब कोई और डुप्लीकेट नहीं होता है तो लूप मर जाता है। सभी ठंडा। * हालांकि * - मैं अभी भी TblName से TblName हटाएं जहां X बनाते हैं ... यह * यह * काम करने के लिए आवश्यक है - बस यह पता लगाना होगा कि क्यों –

1

आप आईडी पंक्तियों आप तो हटाना चाहते हैं की है ...

DELETE FROM table WHERE id IN (1, 4, 7, [id numbers to delete...]) 
+1

यदि आप नीचे कम करने जा रहे हैं तो कम से कम एक कारण दें। –

+0

यह ऐसा करने का लंबा तरीका लगता है ... बहुत मैनुअल ... – Zoidberg

+0

@Zoidberg उनके सवाल का कहना है कि उनके पास 3 डुप्लीकेट हैं और उन्हें दो हटाने की जरूरत है। अगर वह आईडी जानता है तो यह पर्याप्त है। –

3
DELETE FROM Table t1, Table t2 WHERE t1.colDup = t2.colDup AND t1.date < t2.date 

छोड़कर Table से (स्तंभ colDup पर) हर डुप्लिकेट पंक्ति को नष्ट करेगा सबसे पुरानी (यानी lowset date) ।

+0

जो चीज़ मुझे इस बारे में पसंद नहीं है, वह यह मानता है कि एक ऐसा कॉलम है जो इन डुप्लिकेट पंक्तियों को अलग करता है, लेकिन इस प्रश्न में विस्तार की मात्रा दी गई है ... – Zoidberg

+0

आप बिल्कुल सही हैं, लेकिन फिर फिर से; "विस्तार की मात्रा ..."। – jensgram

+0

यह सच है, मुझे लगता है कि मार्क इस सब के बारे में सही है! – Zoidberg

2
DELETE FROM `mytbl` 
    INNER JOIN (
     SELECT 1 FROM `mytbl` 
     GROUP BY `duplicated_column` HAVING COUNT(*)=2 
    ) USING(`id`) 

संपादित करें:

मेरे बुरा, ऊपर क्वेरी काम नहीं करेगा।

मान लिया जाये कि तालिका संरचना:

id पूर्णांक auto_increment

num पूर्णांक # < - यह (मैं जाँच) डुप्लिकेट मानों

साथ स्तंभ निम्न क्वेरी MySQL में काम करेगा है:

DELETE `mytbl` FROM `mytbl` 
    INNER JOIN 
    (
     SELECT `num` FROM `mytbl` 
     GROUP BY `num` HAVING COUNT(*)=2 
    ) AS `tmp` USING (`num`) 

क्वेरी उन पंक्तियों को हटा देगी जिनमें 2 (अधिक नहीं है या ई एलएसई) num कॉलम में डुप्लिकेट मान।

संपादित करें (फिर से):

मैं num स्तंभ पर एक कुंजी जोड़ने के लिए सुझाव देते हैं।

संपादित करें (# 3):

मामले में

कि लेखक दोहराया पंक्तियों नष्ट करने के लिए चाहता था, निम्नलिखित (यह मेरे लिए काम किया) MySQL के लिए काम करना चाहिए:

DELETE `delete_duplicated_rows` FROM `delete_duplicated_rows` 
    NATURAL JOIN (
     SELECT * 
     FROM `delete_duplicated_rows` 
     GROUP BY `num1` HAVING COUNT(*)=2 
    ) AS `der` 

संभालने जबकि तालिका संरचना है:

CREATE TABLE `delete_duplicated_rows` (
    `num1` tinyint(4) DEFAULT NOT NULL, 
    `num2` tinyint(4) DEFAULT NOT NULL 
) ENGINE=MyISAM; 
+1

मुझे नहीं लगता कि यह समाधान वास्तव में समस्या में रखे गए प्रतिबंधों का पालन करता है, है ना?संतानु ने संकेत दिया कि सभी * पंक्तियां * डुप्लिकेट थीं। पहचान कॉलम होने का मतलब है कि पंक्तियां डुप्लीकेट नहीं हैं - और यह एक काफी आसान समस्या बनाती है। मुहम्मद का जवाब बेहतर है। –

+0

@ मार्क ब्रिटिंगहम: आप सही हैं! मैंने अपना जवाब संपादित कर लिया है और मैंने एक और समाधान जोड़ा है। – Dor

1

मुझे लगता है कि प्रत्येक तालिका में अद्वितीय पहचानकर्ता होता है। तो यदि यह मौजूद है तो आप निम्न क्वेरी लिख सकते हैं: तालिका 1 टी 1 से तालिका 1 हटाएं जहां 2> = (तालिका 1 से गिनती (आईडी) चुनें जहां dupColumn = t1.dupColumn) और t1.id में नहीं (अधिकतम (आईडी) चुनें तालिका 1 से जहां dupColumn = t1.dupColumn)

ओओपीएस। ऐसा लगता है कि दूसरे फ़िल्टर का उपयोग करना संभव है तालिका 1 टी 1 से तालिका 1 हटाएं जहां t1.id नहीं है (तालिका 1 से अधिकतम (आईडी) चुनें जहां dupColumn = t1।dupColumn)

4

यह एसक्यूएल सर्वर में काम करता है, हालांकि यह एक भी बयान नहीं है :

Declare @cnt int; 
Select @cnt=COUNT(*) From DupTable Where (Col1=1); -- Assumes you are trying to delete the duplicates where some condition (e.g. Col1=1) is true. 
Delete Top (@cnt-1) From DupTable 

यह भी किसी भी अतिरिक्त assu की आवश्यकता नहीं है mptions (एक और कॉलम के अस्तित्व की तरह जो प्रत्येक पंक्ति अद्वितीय बनाता है)। आखिरकार, संतानु ने कहा था कि पंक्तियां डुप्लिकेट थीं न केवल एक कॉलम थीं।

हालांकि, सही जवाब है, मेरे विचार में, एक वास्तविक तालिका संरचना प्राप्त करने के लिए है। यही है, इस तालिका में एक पहचान कॉलम जोड़ें ताकि आप अपना काम करने के लिए एक एकल SQL कमांड का उपयोग कर सकें। इस तरह:

ALTER TABLE dbo.DupTable ADD 
    IDCol int NOT NULL IDENTITY (1, 1) 
GO 

फिर हटाएं तुच्छ है:

DELETE FROM DupTable WHERE IDCol NOT IN 
    (SELECT MAX(IDCol) FROM DupTable GROUP BY Col1, Col2, Col3) 
1
-- Just to demonstrates Marks example   
    . 
     -- START === 1.0.dbo..DuplicatesTable.TableCreate.sql 
    /****** Object: Table [dbo].[DuplicatesTable] 
     Script Date: 03/29/2010 21:24:02 ******/ 
     IF EXISTS (SELECT * FROM sys.objects 
    WHERE 
object_id = OBJECT_ID(N'[dbo].[DuplicatesTable]') 
AND type in (N'U')) 
     DROP TABLE [dbo].[DuplicatesTable] 
    GO 

    /****** Object: Table [dbo].[DuplicatesTable]  
Script Date: 03/29/2010 21:24:02 ******/ 
    SET ANSI_NULLS ON 
    GO 

    SET QUOTED_IDENTIFIER ON 
    GO 

    CREATE TABLE [dbo].[DuplicatesTable](
     [ColA] [varchar](10) NOT NULL, -- the name of the DuplicatesTable 
     [ColB] [varchar](10) NULL, -- the description of the e DuplicatesTable 
    ) 


    /* 
    <doc> 
    Models a DuplicatesTable for 
    </doc> 

    */ 


    GO 


    --============================================================ DuplicatesTable START 
    declare @ScriptFileName varchar(2000) 
    SELECT @ScriptFileName = '$(ScriptFileName)' 
    SELECT @ScriptFileName + ' --- DuplicatesTable START =========================================' 
    declare @TableName varchar(200) 
    select @TableName = 'DuplicatesTable' 

    SELECT 'SELECT name from sys.tables where name =''' + @TableName + '''' 
    SELECT name from sys.tables 
    where name = @TableName 

    DECLARE @TableCount INT 
    SELECT @TableCount = COUNT(name) from sys.tables 
     where name [email protected] 

    if @TableCount=1 
    SELECT ' DuplicatesTable PASSED. The Table ' + @TableName + ' EXISTS ' 
    ELSE 
    SELECT ' DuplicatesTable FAILED. The Table ' + @TableName + ' DOES NOT EXIST ' 
    SELECT @ScriptFileName + ' --- DuplicatesTable END =========================================' 
    --============================================================ DuplicatesTable END 

    GO 


    -- END === 1.0.dbo..DuplicatesTable.TableCreate.sql 

    . 
    -- START === 1.1..dbo..DuplicatesTable.TableInsert.sql 

    BEGIN TRANSACTION; 
    INSERT INTO [dbo].[DuplicatesTable]([ColA], [ColB]) 
    SELECT N'ColA', N'ColB' UNION ALL 
    SELECT N'ColA', N'ColB' UNION ALL 
    SELECT N'ColA', N'ColB' UNION ALL 
    SELECT N'ColA', N'ColB' UNION ALL 
    SELECT N'ColA', N'ColB' UNION ALL 
    SELECT N'ColA', N'ColB' UNION ALL 
    SELECT N'ColA', N'ColB' UNION ALL 
    SELECT N'ColA1', N'ColB1' UNION ALL 
    SELECT N'ColA1', N'ColB1' UNION ALL 
    SELECT N'ColA1', N'ColB1' UNION ALL 
    SELECT N'ColA1', N'ColB1' UNION ALL 
    SELECT N'ColA1', N'ColB1' UNION ALL 
    SELECT N'ColA1', N'ColB1' UNION ALL 
    SELECT N'ColA1', N'ColB1' 
    COMMIT; 
    RAISERROR (N'[dbo].[DuplicatesTable]: Insert Batch: 1.....Done!', 10, 1) WITH NOWAIT; 
    GO 


    -- END === 1.1..dbo..DuplicatesTable.TableInsert.sql 

    . 
    -- START === 2.0.RemoveDuplicates.Script.sql 
    ALTER TABLE dbo.DuplicatesTable ADD 
      DuplicatesTableId int NOT NULL IDENTITY (1, 1) 
    GO 

    -- Then the delete is trivial: 
    DELETE FROM dbo.DuplicatesTable WHERE DuplicatesTableId NOT IN 
     (SELECT MAX(DuplicatesTableId) FROM dbo.DuplicatesTable GROUP BY ColA , ColB) 

     Select * from DuplicatesTable ; 
    -- END === 2.0.RemoveDuplicates.Script.sql 
संबंधित मुद्दे