2010-12-30 12 views
5

Tôi có một bảng chứa dữ liệu không đáng tiếc và tôi đang cố lọc một số dữ liệu. Tôi chắc chắn rằng LName, FName combonation là duy nhất vì tập dữ liệu đủ nhỏ để xác minh.SQL Xóa hầu hết các hàng trùng lặp

LName, FName, Email 
----- ----- ----- 
Smith Bob [email protected] 
Smith Bob NULL 
Doe Jane NULL 
White Don [email protected] 

Tôi muốn có kết quả truy vấn mang lại bản ghi "trùng lặp" không có email NULL, nhưng vẫn mang lại một email NULL khi không có bản sao.

Ví dụ:

Smith Bob [email protected] 
Doe Jane NULL 
White Don [email protected] 

Tôi nghĩ rằng giải pháp tương tự như Sql, remove duplicate rows by value, nhưng tôi thực sự không hiểu nếu yêu cầu của Người hỏi cũng giống như tôi.

Mọi đề xuất?

Cảm ơn

+0

Cảm ơn các giải pháp từ Cybernate và Michael Goldshteyn. Đã đi với FooLman b/c nó là giải pháp đầu tiên đã làm công việc. Thú vị khi thấy các phương pháp khác nhau để giải quyết. – jimueller

Trả lời

7

Điều này sẽ giảm các hàng trống nếu có bất kỳ giá trị không null nào.

SELECT lname 
     , fname 
     , MIN(email) 
FROM YourTable 
GROUP BY 
     lname 
     , fname 

kịch bản thử nghiệm

DECLARE @Test TABLE (
    LName VARCHAR(32) 
    , FName VARCHAR(32) 
    , Email VARCHAR(32) 
) 

INSERT INTO @Test 
    SELECT 'Smith', 'Bob', '[email protected]' 
    UNION ALL SELECT 'Smith', 'Bob', 'NULL' 
    UNION ALL SELECT 'Doe', 'Jane', 'NULL' 
    UNION ALL SELECT 'White', 'Don', '[email protected]' 

SELECT lname 
     , fname 
     , MIN(Email)   
FROM @Test 
GROUP BY 
     lname 
     , fname 
+1

+1 Đây là giải pháp * dễ nhất * được đăng tải, thực hiện những gì được hỏi. Cộng đồng dường như bị quá tải . –

+0

@Lieven - Nó sẽ không hoạt động! Trường hợp có bất kỳ logic để giữ các hàng null nếu không có bất kỳ những người không null? –

+0

@Martin, truy vấn tạo ra kết quả đầu ra được yêu cầu bởi op cho các đầu vào đã cho đúng không (hoặc tôi đã lên một lần nữa)? –

3

Đây là một câu hỏi tương đối đơn giản có sử dụng SQL tiêu chuẩn và chỉ này:

SELECT * FROM Person P 
WHERE Email IS NOT NULL OR -- Take all people with non-null e-mails 
     Email IS NULL AND -- and all people with null e-mails, as long as 
     NOT EXISTS   -- there is no duplicate record of the same person 
      (SELECT *  -- with a non-null e-mail 
      FROM Person P2 
      WHERE P2.LName=P.LName AND P2.FName=P.FName AND P2.Email IS NOT NULL) 
+0

Bạn ngụ ý rằng 'row_number' không phải là SQL chuẩn? –

+0

Tôi không ngụ ý bất cứ điều gì - chỉ cần cung cấp một giải pháp đơn giản bằng cách sử dụng không có gì hơn một truy vấn SQL tiêu chuẩn liên quan đến một lựa chọn phụ. Tuy nhiên, nếu bạn muốn câu trả lời cho câu hỏi của bạn về ROW_NUMBER, không có câu hỏi nào không phải là SQL chuẩn và không phải là PARTITION BY. –

+0

ANSI SQL 1999 [theo đây] (http://ss64.com/ora/syntax-analytic.html) Không phải là tiêu chuẩn SQL đã từng được chỉ định bởi OP anyway. –

7

Bạn có thể sử dụng ROW_NUMBER() chức năng phân tích:

SELECT * 
    FROM (
       SELECT a.*, ROW_NUMBER() OVER(PARTITION BY LName, FName ORDER BY Email DESC) rnk 
        FROM <YOUR_TABLE> a 
       ) a 
WHERE RNK = 1 
+0

+1 Điều này có thể sẽ hiệu quả hơn là tự tham gia. Kỹ thuật này có thể được sử dụng để xóa cũng như theo câu trả lời của tôi. –

1

Vì có rất nhiều giải pháp SQL đã được đăng, bạn có thể muốn tạo một sửa chữa dữ liệu để loại bỏ dữ liệu xấu, sau đó thêm các ràng buộc cần thiết để ngăn chặn dữ liệu xấu được chèn vào. Dữ liệu xấu trong cơ sở dữ liệu là một tác dụng phụ của thiết kế kém.

+0

Tôi đồng ý và hiểu, nhưng tôi không thể làm gì nhiều về nó trong lĩnh vực CNTT của doanh nghiệp. Đó là thực tế của dữ liệu tôi phải làm việc. – jimueller

+0

@ jrm82, điều quan trọng hơn là phải sửa những thứ như vậy trong ứng dụng Doanh nghiệp! Chỉ vì nó apin không có nghĩa là bạn không nên làm điều đó. Điều này sẽ không gây ra sự cố vĩnh viễn nếu bạn không khắc phục. – HLGEM

+0

HLGEM - Tôi không sở hữu dữ liệu và tôi không có khả năng làm việc theo bất cứ thứ gì mình muốn. – jimueller