2009-03-23 41 views
7

Tôi đã cung cấp cho khách hàng truy vấn sau để xóa số điện thoại trùng lặp không. các bản ghi trong một cơ sở dữ liệu MSSQL, nhưng bây giờ họ cũng cần phải làm điều đó trên MySQL, và họ báo cáo rằng MySQL phàn nàn về định dạng của truy vấn. Tôi đã bao gồm các thiết lập của một bảng thử nghiệm với các bản sao cho mẫu mã của tôi, nhưng truy vấn xóa thực tế là những gì đếm.Cách xóa Bản sao trong bảng MySQL

Tôi yêu cầu điều này trong sự thiếu hiểu biết và khẩn cấp, vì tôi vẫn bận tải xuống và cài đặt MySQL, và chỉ có thể ai đó có thể trợ giúp trong thời gian đó.

create table bkPhone 
(
    phoneNo nvarchar(20), 
    firstName nvarchar(20), 
    lastName nvarchar(20) 
) 
GO 

insert bkPhone values('0783313780','Brady','Kelly') 
insert bkPhone values('0845319792','Mark','Smith') 
insert bkPhone values('0834976958','Bill','Jones') 
insert bkPhone values('0845319792','Mark','Smith') 
insert bkPhone values('0828329792','Mickey','Mouse') 
insert bkPhone values('0834976958','Bill','Jones') 

alter table bkPhone add phoneId int identity 

delete from bkPhone 
where phoneId not in 
(
    select min(phoneId) 
    from bkPhone 
    group by phoneNo,firstName,lastName 
    having count(*) >= 1 
) 
+1

Có vẻ ổn với tôi. Có phải họ đang sử dụng một phiên bản MySQL hỗ trợ các truy vấn con không? –

+0

Tại sao 'có số (*)> = 1' ?? Khi nó không bao giờ? – RichardTheKiwi

Trả lời

14

Nhiều cách dẫn đến Rome. Đây là một. Nó rất nhanh. Vì vậy, bạn có thể sử dụng nó với cơ sở dữ liệu lớn. Đừng quên phân. Bí quyết là: làm cho điện thoạiKhông có gì độc đáo và sử dụng "bỏ qua".

drop table if exists bkPhone_template; 
create table bkPhone_template (
     phoneNo varchar(20), 
     firstName varchar(20), 
     lastName varchar(20) 
); 

insert into bkPhone_template values('0783313780','Brady','Kelly'); 
insert into bkPhone_template values('0845319792','Mark','Smith'); 
insert into bkPhone_template values('0834976958','Bill','Jones'); 
insert into bkPhone_template values('0845319792','Mark','Smith'); 
insert into bkPhone_template values('0828329792','Mickey','Mouse'); 
insert into bkPhone_template values('0834976958','Bill','Jones'); 

drop table if exists bkPhone; 
create table bkPhone like bkPhone_template; 
alter table bkPhone add unique (phoneNo); 

insert ignore into bkPhone (phoneNo,firstName,lastName) select phoneNo,firstName,lastName from bkPhone_template; 

drop table bkPhone_template; 

Nếu bảng dữ liệu đã tồn tại, khi đó bạn chỉ phải chạy bảng tạo với lựa chọn chèn bỏ sau. Cuối cùng, bạn phải chạy một số câu lệnh đổi tên bảng. Đó là tất cả.

Cách giải quyết này nhanh hơn nhiều, sau đó là thao tác xóa.

+0

Cảm ơn bạn đã đào tạo hai phần về MySQL. Bây giờ tôi có 'thích' để tạo bảng, và 'bỏ qua' trong kho vũ khí của tôi. – ProfK

+2

Lưu ý BTW (bình luận dài sau khi trả lời do trùng lặp liên kết) mà bạn chỉ có thể sử dụng 'ALTER IGNORE TABLE ADD UNIQUE (phoneNo)', mà lặng lẽ jsut loại bỏ các bản sao trong bảng mà không cần phải tạo một số khác. – Wrikken

5

Bạn có thể chọn ra những cái độc đáo bởi:

select distinct(phoneNo) from bkPhone 

và đặt chúng vào một bảng, xóa bảng cũ và đổi tên cái mới cho tên cũ.

+0

Do sự đơn giản của kịch bản, cho phép các bảng mới và bị bỏ, đây là cách đơn giản nhất. giải pháp hiệu quả nhất. Cảm ơn. – ProfK

2

MySQL phàn nàn, bởi vì nó không có ý nghĩa. Bạn cố gắng tổng hợp bằng cách sử dụng cột min() mà bạn nhóm.

Bây giờ, nếu bạn đang cố gắng để xóa số điện thoại trùng lặp cho cùng một người, SQL nên là:

delete from bkPhone 
where phoneId not in 
(
     select min(phoneId) 
     from bkPhone 
     group by firstName,lastName /* i.e. grouping by person and NOT grouping by phoneId */ 
     having count(*) >= 1 
) 
+0

Tuyệt vời. Một trường hợp sử dụng khác cho mệnh đề 'having' đáng yêu :-) Nhưng tôi nghĩ bạn nên viết'> ', thay vì'> = '. Điều đó có thể đẩy nhanh mọi thứ –

+0

Tôi không thấy điểm này 'có' chút nào. Khi nó đứng, nó phải luôn luôn là sự thật, vì vậy nó là vô nghĩa. Và nếu bạn thay đổi nó thành '> 1', thì các hàng * không có * các từ khóa trùng lặp sẽ bị bỏ qua từ' select' bên trong và do đó * bị loại bỏ * bởi 'delete' bên ngoài. Không phải những gì bạn muốn, tôi tin. – MvG

+0

@LukasEder: với '>' sẽ xóa tất cả các mục nhập, chỉ có một điện thoại duy nhất. Tôi nghĩ rằng bạn đã không nhận thấy rằng có 'không' trong tình trạng này. – vartec

Các vấn đề liên quan