Làm cách nào để xóa một hàng nhất định khỏi bảng mysql có cùng giá trị cột?


153

Tôi có một vấn đề với các truy vấn của tôi trong MySQL. Bảng của tôi có 4 cột và trông giống như thế này:

id_users    id_product    quantity    date
 1              2              1       2013
 1              2              1       2013
 2              2              1       2013
 1              3              1       2013

id_usersid_productlà khóa ngoại từ các bảng khác nhau.

Điều tôi muốn là xóa chỉ một hàng:

1     2     1    2013

Mà xuất hiện hai lần, vì vậy tôi chỉ muốn xóa nó.

Tôi đã thử truy vấn này:

delete from orders where id_users = 1 and id_product = 2

Nhưng nó sẽ xóa cả hai (vì chúng được nhân đôi). Bất kỳ gợi ý về giải quyết vấn đề này?

Câu trả lời:


208

Thêm một limitvào truy vấn xóa

delete from orders 
where id_users = 1 and id_product = 2
limit 1

3
Điều này chỉ xóa một hàng. Nếu có 3 với id người dùng và sản phẩm này thì 2 sẽ vẫn còn.
Cướp

10
Có, OP nói rằng anh ấy muốn xóa 1 hàng. Đó là những gì truy vấn của tôi làm.
juergen d

2
Có, nhưng tôi nghĩ rằng đây không phải là những gì anh ấy / cô ấy muốn.
Cướp

3
Cảm ơn bạn Juergen. Đây là tất cả những gì tôi cần!
Dani

3
Điều OP thực sự cần làm là kiểm tra đầu tiên những hàng nào được sao chép sau đó xóa các bản sao.
wbinky

64

Tất cả các bảng phải có khóa chính (bao gồm một hoặc nhiều cột), các hàng trùng lặp không có ý nghĩa trong cơ sở dữ liệu quan hệ. Bạn có thể giới hạn số lượng hàng xóa bằng cách sử dụng LIMIT:

DELETE FROM orders WHERE id_users = 1 AND id_product = 2 LIMIT 1

Nhưng điều đó chỉ giải quyết vấn đề hiện tại của bạn, bạn chắc chắn nên làm việc với vấn đề lớn hơn bằng cách xác định các khóa chính.


1
Điều này là tốt để đề cập rằng khóa chính phải là duy nhất trong một cơ sở dữ liệu quan hệ.
Paul

1
@Paul Đây chính xác là những gì tôi sắp nói. Nhưng đừng quên khóa duy nhất không cần thiết có nghĩa là khóa chính.
Ryan Fung

20

Bạn cần chỉ định số lượng hàng cần xóa. Trong trường hợp của bạn (và tôi cho rằng bạn chỉ muốn giữ một cái), điều này có thể được thực hiện như thế này:

DELETE FROM your_table WHERE id_users=1 AND id_product=2
LIMIT (SELECT COUNT(*)-1 FROM your_table WHERE id_users=1 AND id_product=2)

Cảm ơn Rob, nhưng không ... Tôi chỉ muốn xóa một hàng duy nhất, không chỉ giữ một hàng
Dani

Điều này không làm việc cho tôi trong 5.5.40, nó gây ra lỗi cú pháp. Như đã đề cập ở đây: stackoverflow.com/a/578926/1076075 , có vẻ như chúng ta không thể sử dụng truy vấn con để chỉ định giá trị của mệnh đề LIMIT. Đối với bất kỳ ai đang cố gắng thực hiện theo cách này, hãy kiểm tra điều này: stackoverflow.com/q/578867/1076075
Bharadwaj Srigiriraju

8

Cách tốt nhất để thiết kế bảng là thêm một hàng tạm thời làm tăng tự động và giữ làm khóa chính. Vì vậy, chúng ta có thể tránh các vấn đề trên.


1
Hoặc một hàng cố định. Tôi biết đây là một câu hỏi cũ, nhưng tôi mặc dù tôi nên nói nó. Id được sử dụng cho loại tình huống này. Nếu bạn lo lắng về dung lượng: BIGINT chỉ có 8 byte!
Ismael Miguel

5

Đã có câu trả lời cho việc xóa hàng bằng cách LIMIT. Tốt nhất bạn nên có khóa chính trong bảng của mình. Nhưng nếu không có.

Tôi sẽ đưa ra những cách khác:

  1. Bằng cách tạo chỉ mục duy nhất

Tôi thấy id_users và id_product phải là duy nhất trong ví dụ của bạn.

ALTER IGNORE TABLE orders ADD UNIQUE INDEX unique_columns_index (id_users, id_product)

Chúng sẽ xóa các hàng trùng lặp với cùng một dữ liệu.

Nhưng nếu bạn vẫn gặp lỗi, ngay cả khi bạn sử dụng mệnh đề IGNORE, hãy thử điều này:

ALTER TABLE orders ENGINE MyISAM;
ALTER IGNORE TABLE orders ADD UNIQUE INDEX unique_columns_index (id_users, id_product)
ALTER TABLE orders ENGINE InnoDB; 
  1. Bằng cách tạo lại bảng

Nếu có nhiều hàng có giá trị trùng lặp, thì bạn cũng có thể tạo lại bảng

RENAME TABLE `orders` TO `orders2`;

CREATE TABLE `orders` 
SELECT * FROM `orders2` GROUP BY id_users, id_product;

1

Bạn phải thêm một id tự động tăng cho mỗi hàng, sau đó bạn có thể xóa hàng theo id của nó. vì vậy bảng của bạn sẽ có một id duy nhất cho mỗi hàng và id_user, id_product ecc ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.