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.