Xóa tất cả các hàng trong một bảng dựa trên một bảng khác


80

Tôi dường như không bao giờ nhớ được truy vấn này!

Tôi muốn xóa tất cả các hàng trong table1 có ID giống như trong Table2.

Vì thế:

DELETE table1 t1
 WHERE t1.ID = t2.ID

Tôi biết tôi có thể thực hiện ID WHERE IN (CHỌN ID TỪ table2) nhưng tôi muốn thực hiện truy vấn này bằng cách sử dụng JOIN nếu có thể.


Tại sao bạn muốn tham gia?
tster

Bạn lên kế hoạch phải làm gì với câu hỏi này: stackoverflow.com/questions/1590709/...
OMG Ngựa Non

Bởi vì gia nhập thường nhanh hơn.
HLGEM

@tster Có lẽ đó là một bảng tạm thời của id đó cần phải bị xóa
Stephen Mesa

1
@HLGEM Bạn đang nói trình tối ưu hóa truy vấn không đủ thông minh để thực hiện thao tác "xóa khỏi X trong đó XY IN (chọn Foo từ Thanh)" đơn giản nhanh như thực hiện một phép nối? Tôi sẽ tin tưởng trình tối ưu hóa hơn cảm giác ruột.
tster

Câu trả lời:



87
DELETE t1 
FROM Table1 t1
JOIN Table2 t2 ON t1.ID = t2.ID;

Tôi luôn sử dụng bí danh trong câu lệnh xóa vì nó ngăn chặn sự cố tình cờ

DELETE Table1 

gây ra khi không đánh dấu được toàn bộ truy vấn trước khi chạy nó.


5
Hầu hết ủng hộ cho nhận xét "luôn sử dụng bí danh". Ý tưởng tuyệt vời.
rosscova 13/09/19

35

Không có giải pháp nào trong ANSI SQL để sử dụng các phép nối trong việc xóa, AFAIK.

DELETE FROM Table1
WHERE Table1.id IN (SELECT Table2.id FROM Table2)

Chỉnh sửa sau

Giải pháp khác (đôi khi hoạt động nhanh hơn):

DELETE FROM Table1
WHERE EXISTS( SELECT 1 FROM Table2 Where Table1.id = Table2.id)

Câu hỏi của anh ấy nói ở cuối rằng anh ấy muốn sử dụng một phép nối hơn là mệnh đề IN.
Stephen Mesa

21

Việc triển khai PostgreSQL sẽ là:

DELETE FROM t1
USING t2
WHERE t1.id = t2.id;

4

Thử cái này:

DELETE Table1
FROM Table1 t1, Table2 t2
WHERE t1.ID = t2.ID;

hoặc là

DELETE Table1
FROM Table1 t1 INNER JOIN Table2 t2 ON t1.ID = t2.ID;

3

Tôi nghĩ rằng bạn có thể đạt được hiệu suất cao hơn một chút nếu bạn thử điều này

DELETE FROM Table1
WHERE EXISTS (
  SELECT 1
  FROM Table2
  WHERE Table1.ID = Table2.ID
)

3

Thao tác này sẽ xóa tất cả các hàng Table1phù hợp với tiêu chí:

DELETE Table1 
FROM Table2 
WHERE Table1.JoinColumn = Table2.JoinColumn And Table1.SomeStuff = 'SomeStuff'

2

Tìm thấy liên kết này hữu ích

Được sao chép từ đó

Thông thường, người ta muốn xóa một số bản ghi khỏi bảng dựa trên tiêu chí trong bảng khác. Làm cách nào để xóa khỏi một trong các bảng đó mà không xóa các bản ghi trong cả hai bảng?

DELETE DeletingFromTable
     FROM DeletingFromTable INNER JOIN CriteriaTable
     ON DeletingFromTable.field_id = CriteriaTable.id
     WHERE CriteriaTable.criteria = "value";

Điều quan trọng là bạn chỉ định tên của bảng sẽ bị xóa làm CHỌN. Vì vậy, JOIN và WHERE thực hiện lựa chọn và giới hạn, trong khi DELETE thực hiện việc xóa. Tuy nhiên, bạn không bị giới hạn chỉ trong một bảng. Nếu bạn có mối quan hệ nhiều-nhiều (ví dụ: Tạp chí và Người đăng ký, do một Đăng ký tham gia) và bạn đang xóa Người đăng ký, bạn cũng cần xóa mọi bản ghi tiềm năng khỏi mô hình tham gia.

 DELETE subscribers, subscriptions
     FROM subscribers INNER JOIN subscriptions 
       ON subscribers.id = subscriptions.subscriber_id
     INNER JOIN magazines 
       ON subscriptions.magazine_id = magazines.id
     WHERE subscribers.name='Wes';

Việc xóa các bản ghi với một phép kết hợp cũng có thể được thực hiện bằng LEFT JOIN và WHERE để xem liệu bảng đã tham gia có phải là NULL hay không, do đó bạn có thể xóa các bản ghi trong một bảng không có khớp (như để chuẩn bị thêm mối quan hệ) ) Ví dụ bài đến.


2

Vì OP không yêu cầu một DB cụ thể, tốt hơn nên sử dụng một tuyên bố tuân thủ tiêu chuẩn. Chỉ có MERGEtrong tiêu chuẩn SQL để xóa (hoặc cập nhật) các hàng trong khi tham gia một cái gì đó trên bảng đích.

merge table1 t1
    using (
        select t2.ID
            from table2 t2
    ) as d
    on t1.ID = d.ID
    when matched then delete;

MERGEcó ngữ nghĩa chặt chẽ hơn, bảo vệ khỏi một số trường hợp lỗi có thể không được chú ý DELETE ... FROM. Nó thực thi 'tính duy nhất' của đối sánh: nếu nhiều hàng trong nguồn (câu lệnh bên trong using) khớp với cùng một hàng trong mục tiêu, hợp nhất phải bị hủy và lỗi phải được tạo ra bởi công cụ SQL.


đây là sạch hơn delete-tham gia xây dựng
asakura89


0

Để xóa bản ghi bảng dựa trên một bảng khác

     Delete From Table1 a,Table2 b where a.id=b.id

    Or

      DELETE FROM Table1
    WHERE Table1.id IN (SELECT Table2.id FROM Table2)

  Or

        DELETE Table1
     FROM Table1 t1 INNER JOIN Table2 t2 ON t1.ID = t2.ID;

0

Cái này cũ mà tôi biết, nhưng chỉ là một gợi ý cho bất kỳ ai sử dụng cái mông này để tham khảo. Tôi vừa thử điều này và nếu bạn đang sử dụng Oracle, thì JOIN không hoạt động trong các câu lệnh DELETE. Bạn nhận được một thông báo sau:

ORA-00933: Lệnh SQL không được kết thúc đúng cách.


Xem câu trả lời này cho một câu hỏi khác để biết ví dụ về cách viết lệnh xóa với phép nối trong Oracle.
Frédéric

0

Mặc dù OP không muốn sử dụng câu lệnh 'in', để trả lời Ankur Gupta, đây là cách dễ nhất mà tôi tìm thấy để xóa các bản ghi trong một bảng mà không tồn tại trong bảng khác, trong mối quan hệ một - nhiều. :

DELETE
FROM Table1 as t1
WHERE ID_Number NOT IN
(SELECT ID_Number FROM Table2 as t2)

Đối với tôi, làm việc như một sự quyến rũ trong Access 2016.


0

Tôi thường làm những việc như ví dụ trang điểm sau đây. (Ví dụ này là từ Informix SE chạy trên Linux.)

Điểm của ví dụ này là xóa tất cả các bản ghi giao dịch miễn trừ / hủy bỏ bất động sản - vì ứng dụng hủy bỏ có một lỗi - dựa trên thông tin trong bảng real_estate.

Trong trường hợp này last_update != nullcó nghĩa là tài khoản chưa bị đóng và res_exempt != 'p'có nghĩa là tài khoản không phải là tài sản cá nhân (thiết bị / đồ đạc thương mại).

delete from trans 
where   yr = '16'
and     tran_date = '01/22/2016'
and     acct_type = 'r'
and     tran_type = 'a'
and     bill_no in
(select acct_no from real_estate where last_update is not null
 and res_exempt != 'p');

Tôi thích phương pháp này, vì tiêu chí lọc - ít nhất là đối với tôi - dễ đọc hơn trong khi tạo truy vấn và để hiểu trong nhiều tháng kể từ bây giờ khi tôi nhìn vào nó và tự hỏi mình đang nghĩ gì.


0
delete
    table1
from 
    t2
where
    table1.ID=t2.ID

Hoạt động trên mssql

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.