Bir sorguda iki tablodan sil


84

MySQL'de iki tablom var

#messages table  : 
messageid
messagetitle 
.
.

#usersmessages table 
usersmessageid 
messageid
userid
.
.

Şimdi mesajlar tablosundan silmek istersem sorun değil. Ancak messageid ile mesajı sildiğimde kayıt hala kullanıcı mesajında ​​mevcut ve bu iki tablodan aynı anda silmem gerekiyor.

Şu sorguyu kullandım:

DELETE FROM messages LEFT JOIN usersmessages USING(messageid) WHERE messageid='1' ; 

Sonra test ederim

   DELETE FROM messages , usersmessages 
   WHERE messages.messageid = usersmessages.messageid 
   and messageid='1' ; 

Ancak bu iki sorgu bu görevi yerine getirmiyor.

Yanıtlar:


137

Onları noktalı virgülle ayıramaz mısın?

Delete from messages where messageid = '1';
Delete from usersmessages where messageid = '1'

VEYA

Sadece INNER JOINaşağıdaki gibi kullanın

DELETE messages , usersmessages  FROM messages  INNER JOIN usersmessages  
WHERE messages.messageid= usersmessages.messageid and messages.messageid = '1'

1
bu kodu bir döngüye sokmak istersem ne olur? kesinlikle noktalı virgül koyabileceğimi biliyorum.
mehdi

1
Bir döngüye konulabilir. Bunu programlı olarak yapabilir ve mesaj kimliğini parametre olarak gönderebilirsiniz. Aynı kimliği göndermeye devam etmediğiniz sürece, silme işlemini defalarca yapmaz.
Eric

4
Bunu iki sorguda yaparsanız, bunu gerçekten bir işlemde sarmalısınız. Bir döngüde silme sorgularını çalıştırmaya gelince, tüm silme işlemlerini yapmak için tek bir sorgu formüle etmeniz daha iyidir.
JohnFx


21
SQL Server ile çalışmıyor: ',' yakınında yanlış sözdizimi.
Paul-Sebastian Manole

45
DELETE a.*, b.* 
FROM messages a 
LEFT JOIN usersmessages b 
ON b.messageid = a.messageid 
WHERE a.messageid = 1

çeviri: tablosundan silme mesajlar tablo halinde messageid = 1, uersmessages messageid = messageid tablo içinde vardır mesajların , söz konusu satırını silin uersmessages masaya.


tümü için yorum: Bu örnekte gösterildiği gibi, silme işleminin hangi tabloda çalışması gerektiğini belirtmek önemlidir. Harika gönderi @angry_kiwi
Raphael_b

Sırayı değiştirmem gerekiyordu, KULLANICI mesajlarından B LEFT JOIN mesajları a
Pablo

15

Ya bir oluşturmalısınız FOREIGN KEYile ON DELETE CASCADE:

ALTER TABLE usersmessages
ADD CONSTRAINT fk_usermessages_messageid
FOREIGN KEY (messageid)
REFERENCES messages (messageid)
ON DELETE CASCADE

veya bir işlemde iki sorgu kullanarak yapın:

START TRANSACTION;;

DELETE
FROM    usermessages
WHERE   messageid = 1

DELETE
FROM    messages
WHERE   messageid = 1;

COMMIT;

İşlem yalnızca InnoDBtabloları etkiler .


3
Sen olabilir tek sorguda birden çok tablodan silmek! dev.mysql.com/doc/refman/5.0/en/delete.html
txwikinger

Evet yapabilirsin! Ama bana göre ... cevabımın söylediğini yapmak daha kolay.
Eric

Çağlayanı benzer bir masama ekledim. Sadece 1 tablodan silmeye çalıştığımda, kaydı sildi ve ilgili olanı sahipsiz bıraktı. Kısıtlamanın ne faydası var?
barfoon

@barfoon: masanız InnoDBmı?
Quassnoi

@Quassnoi Oops! Kesinlikle ne kadar aptal olduğunu düşündüm. Tüm tablolar MyISAM'dır. İçlerinde veriler varken hepsini anında değiştirebilir miyim? Yoksa bununla ilgili bir sorun mu var?
barfoon

7

İki seçeneğiniz var:

İlk olarak, bir işlemin içinde iki ifade yapın:

BEGIN;
  DELETE FROM messages WHERE messageid = 1;
  DELETE FROM usermessages WHERE messageid = 1;
COMMIT;

Veya bir yabancı anahtarla ON DELETE CASCADE kurulumuna sahip olabilirsiniz. Bu daha iyi bir yaklaşımdır.

CREATE TABLE parent (
  id INT NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE child (
  id INT, parent_id INT,
  FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
);

Daha SİL ÇORUH AÇIK okuyabilirsiniz burada .


7

JOINS'e gerek yok:

DELETE m, um FROM messages m, usersmessages um

WHERE m.messageid = 1 

AND m.messageid = um.messageid 

6
DELETE message.*, usersmessage.* from users, usersmessage WHERE message.messageid=usersmessage.messageid AND message.messageid='1'

6

OP, silme işleminden sonra tablo diğer adlarını eksik

DELETE t1, t2 
FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id 
WHERE t1.id = some_id

3
Cevabınız için teşekkürler. Bunun neden işe yaradığını ve OPs çözümünün neden işe yaramadığını açıklamaya çalışırsanız daha yararlı olacaktır.
DdW

1

Bunu dene lütfen

DELETE FROM messages,usersmessages

USING messages

INNER JOIN usermessages on (messages.messageid = usersmessages.messageid)

WHERE messages.messsageid='1'

0

Bunu dene..

DELETE a.*, b.*  
FROM table1 as a, table2 as b  
WHERE a.id=[Your value here] and b.id=[Your value here]

idÖrnek bir sütun olarak izin verdim .

Bunun yardımcı olmasına sevindim. :)


Yıldız işaretlerinin ( *) düzgün bir şekilde işlenmesi için sorguyu önünde 4 boşluk bırakarak girintilenmeniz gerekir.
Al.G.

0

Ayrıca, her iki sütun da aynı sütun adına 2 veya daha fazla sahip olduğunda belirli bir değeri silmek için bu şekilde kullanabilirsiniz.

DELETE project , create_test  FROM project INNER JOIN create_test
WHERE project.project_name='Trail' and  create_test.project_name ='Trail' and project.uid= create_test.uid = '1';

0

Burada bahsedilmeyen başka bir yol var (henüz performansını tam olarak test etmedim), tüm tablolar için dizi ayarlayabilirsiniz -> silmek istediğiniz satırlar aşağıdaki gibi

// set your tables array
$array = ['table1', 'table2', 'table3'];


// loop through each table
for($i = 0; $i < count($array); $i++){

 // get each single array
 $single_array = $array[$i];

 // build your query
 $query = "DELETE FROM $single_array WHERE id = 'id'";

 // prepare the query and get the connection
 $data = con::GetCon()->prepare($query);

 // execute the action
 $data->execute();
}

daha sonra kullanıcıyı ana sayfaya yönlendirebilirsiniz.

header('LOCATION:' . $home_page);

umarım bu birine yardımcı olur :)

Teşekkürler


Bu birisine yardımcı olabilir ... PHP'ye benziyor, bunun ille de sorunun kapsamında olduğunu sanmıyorum :)
Tom Bush
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.