মাইএসকিউএল এ যোগ দিয়ে মুছুন


501

আমার টেবিলগুলি তৈরি করার জন্য এখানে স্ক্রিপ্ট রয়েছে:

CREATE TABLE clients (
   client_i INT(11),
   PRIMARY KEY (client_id)
);
CREATE TABLE projects (
   project_id INT(11) UNSIGNED,
   client_id INT(11) UNSIGNED,
   PRIMARY KEY (project_id)
);
CREATE TABLE posts (
   post_id INT(11) UNSIGNED,
   project_id INT(11) UNSIGNED,
   PRIMARY KEY (post_id)
);

আমার পিএইচপি কোডে, ক্লায়েন্টকে মুছে ফেলার সময়, আমি সমস্ত প্রকল্পের পোস্টগুলি মুছতে চাই:

DELETE 
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id;

পোস্ট টেবিলের কোনও বিদেশী কী নেই client_id, কেবলমাত্র project_id। যে প্রকল্পগুলি উত্তীর্ণ হয়েছে তাদের পোস্টগুলি মুছতে চাই client_id

কোনও পোস্ট মোছা না হওয়ায় এটি এখনই কাজ করছে না।


10
আমি মনে করি যে ইয়াহোসেফের উত্তরটি অবশ্যই গ্রহণযোগ্য হওয়া উচিত, যেহেতু তিনি আপনার অনুরোধ অনুসারে জয়েন ব্যবহার করেন এবং এটি ইউকনডুড প্রস্তাবিত হিসাবে একটি আইএন ক্লজ ব্যবহার করার চেয়ে আরও ভাল অভিনয় করে ...
জেরার্ডো গ্রিগনিলি

2
পছন্দসই প্যাটার্নটি DELETE posts FROM posts JOIN projects ...একটি IN (subquery)প্যাটার্নের পরিবর্তে একটি । (
ইয়াহোসেফের

@ জেরার্ডো গ্রিগনলি, এটি কোনও নির্দিষ্ট ইঞ্জিন বা মাইএসকিউএলের সংস্করণটির জন্য আরও ভাল পারফর্ম করে? দু'দিকের প্রশ্নের আলাদা আলাদা কোনও কার্য সম্পাদন করার কোনও কারণ নেই, যেহেতু এএফএআইকি তারা অভিন্ন। অবশ্যই, যদি আমি ছিল সব আমার প্রশ্নের সাথে অপটিমাইজার জন্য এক পয়সাও কিছু মূঢ় .... করেনি
পল ড্র্যাপার

আপনি aliasটেবিলের নামের জন্যও এটি ব্যবহার করতে পারেন।
বিনিয়াম

উত্তর:


1253

আপনাকে কেবল উল্লেখ করতে হবে যে আপনি postsটেবিল থেকে এন্ট্রিগুলি মুছতে চান :

DELETE posts
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id

সম্পাদনা: আরও তথ্যের জন্য আপনি এই বিকল্প উত্তরটি দেখতে পারেন


117
এটি লক্ষ করা উচিত যে এটি সঠিক উত্তর কারণ যোগদানের ফলে সারণীটি আর পরিষ্কার হয় না, তাই আপনাকে "সাধারণ পোস্টগুলি থেকে মুছে ফেলুন" পোস্টগুলির পরিবর্তে "পোস্ট পোস্ট থেকে ডিলিট পোস্ট" ব্যবহার করতে বাধ্য করে। ধন্যবাদ!
সায়ানোপোল্লো

8
দ্রষ্টব্য আপনি এখানে 'হিসাবে' পদ্ধতি ব্যবহার করতে পারবেন না যেমন পি.প্রজেক্ট_আইডিতে পি হিসাবে অভ্যন্তরীণ যোগদান প্রকল্পগুলি ...
জাজেপার

14
প্রকৃতপক্ষে আপনি যুক্ত টেবিলগুলির জন্য একটি উপনাম ব্যবহার করতে পারেন, তবে মূল টেবিলের জন্য (পোস্টগুলি) নয়। "প্রকল্পের অন্তর্ভুক্ত প্রকল্পের পোস্টগুলি পি.পি.প্রজেক্ট_আইডি = পোস্ট.প্রজেক্ট_আইডির পোস্টগুলি মুছে ফেলুন"
ওয়েবয়েড


14
এটি সেরা উত্তর কারণ আপনি এমনকি একটি ক্রিয়ায় উভয় টেবিল থেকে মুছতে পারেনDELETE posts , projects FROM posts INNER JOIN projects ON projects.project_id = posts.project_id WHERE projects.client_id = :client_id
বিকাশকারী

84

যেহেতু আপনি একাধিক সারণী নির্বাচন করছেন তাই মুছে ফেলার জন্য সারণীটি আর স্পষ্ট নয়। আপনাকে নির্বাচন করতে হবে :

DELETE posts FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id

এই ক্ষেত্রে, table_name1এবং table_name2একই টেবিল, তাই এটি কাজ করবে:

DELETE projects FROM posts INNER JOIN [...]

আপনি চাইলে উভয় টেবিল থেকে এমনকি মুছতে পারেন:

DELETE posts, projects FROM posts INNER JOIN [...]

নোট করুন order byএবং limit মাল্টি-টেবিল মোছার জন্য কাজ করবেন না

আরও সচেতন থাকুন যে আপনি যদি কোনও টেবিলের জন্য একটি উপনাম ঘোষণা করেন, সারণির উল্লেখ করার সময় আপনাকে অবশ্যই উপনামটি ব্যবহার করতে হবে:

DELETE p FROM posts as p INNER JOIN [...]

কার্পেটস্মোকার এবং ইত্যাদি থেকে অবদান


3
আপনি যদি আরও ভাল উত্তর দিচ্ছেন - কমপক্ষে আপনি এসকিউএলকে আরও পঠনযোগ্য করে তুলতে পারেন। এই প্রশ্নের অন্যান্য সমস্ত এসকিউএল রেফারেন্সে মূলশব্দকে মূলধন করা হয়েছে (০ টি ভোটের সাথে একটি বাদে)। আপনি কেন আমার সম্পাদনাগুলি উল্টিয়েছিলেন তা আমি নিশ্চিত নই।
ইয়েসোসেফ

3
@ ইয়াহোসেফ, এমন একদল লোক আছেন যারা সিএপিএসকে সত্যই চমকপ্রদ মনে করেন। আমি বিশ্বাস করি যে আমি একমাত্র নই, আমি বেশ কয়েকজনকে ছোট হাতের স্টাইলে যেতে দেখেছি।
পেসারিয়ার

1
যথেষ্ট ন্যায্য - আমি আপনার উত্তরটি আপনার পছন্দ মতো লেখার অধিকারকে সম্মান করি;)
ইয়াহোসেফ

7
ক্যাপগুলি / কোনও ক্যাপস আলোচনায় যুক্ত করতে, সত্য, আপনি আপনার পছন্দমতো স্টাইল ব্যবহার করতে পারেন তবে আপনার উত্তরে আপনি যেখানে শৈলীগুলি পছন্দ করেন ঠিক ONতেমন মিশ্রণ করছেন - এটি মূলধনযুক্ত is কম অভিজ্ঞ বিকাশকারীদের কাছে, এটি বোঝাতে পারে যে শৈলীর দিক থেকে অগোছালো এবং বেমানান হওয়া ঠিক আছে।
শেড

16
ক্যাপস কীওয়ার্ডগুলি চমকপ্রদ নয়। ); তারা শব্দপদগুলি পাঠযোগ্য তৈরি করছেন
রেড ইণ্ডিয়ান গোষ্ঠীপতি

50

বা একই জিনিসটি, কিছুটা আলাদা (আইএমও বন্ধুবান্ধব) সিনট্যাক্স সহ:

DELETE FROM posts 
USING posts, projects 
WHERE projects.project_id = posts.project_id AND projects.client_id = :client_id;

বিটিডব্লিউ, সাথে মাইএসকিএল ব্যবহার করে প্রায় সবসময় সাব-কোয়েরির চেয়ে দ্রুততর উপায় ...


ব্যবহারের অর্থ কী?
সিএমসিডিগ্রাগনকাই

1
এর ভাল ব্যাখ্যা USING:
স্ট্যাকওভারফ্লো

10
@ বিগটেক্স 777: দয়া করে নোট করুন যে নির্বাচনী বিবৃতিতে ব্যবহার করা কীওয়ার্ডটি মুছে ফেলতে একটি বিবৃতিতে একই কীওয়ার্ডটির সাথে খুব একটা সম্পর্ক রাখে না। নির্বাচনগুলিতে এটি যোগদানের জন্য কলামগুলির তালিকা নির্দিষ্ট করে, যখন মুছে ফেলতে এটি একটি যোগদানের সমস্ত টেবিলের তালিকা
ivanhoe

42

আপনি এটির মতো ALIASও ব্যবহার করতে পারেন এটি কেবল এটি ব্যবহার করে আমার ডাটাবেসে! টেবিল থেকে মুছে ফেলা প্রয়োজন!

DELETE t FROM posts t
INNER JOIN projects p ON t.project_id = p.project_id
AND t.client_id = p.client_id

1
টেবিলের নামগুলি পুনরাবৃত্তি করা এড়াতে যৌগিক কীগুলিতে যোগদানের জন্য এটি দরকারী
মার্চেজ

1
"আসলে আপনি যোগদানের টেবিলগুলির জন্য একটি উপাত্ত ব্যবহার করতে পারেন, তবে মূল টেবিলের জন্য নয় (পোস্টগুলি) '' পোস্টে অন্তর্ভুক্ত পোস্টগুলি অন্তর্ভুক্ত করুন প্রজেক্ট_আইডি = পোস্ট.প্রজেক্ট_িড '" - @ ওয়েবোয়েড
জিফ গিলবার্ট

2
প্রকৃতপক্ষে ( dev.mysql.com/doc/refman/5.0/en/delete.html থেকে উদ্ধৃতি ) "আপনি যদি কোনও টেবিলের জন্য কোনও এলিয়াস ঘোষণা করেন, সারণির উল্লেখ করার সময় আপনাকে অবশ্যই উপনামটি ব্যবহার করতে হবে: t1 as T1 থেকে পরীক্ষা মুছে ফেলুন, টেস্ট 2 যেখানে ... "সুতরাং একটি উলাম ব্যবহার করা ভাল।
পিটার বোয়ার্স

25

আমি এর subquery সমাধান আরও বেশি অভ্যস্ত, কিন্তু আমি মাইএসকিউএল এ চেষ্টা করে নি:

DELETE  FROM posts
WHERE   project_id IN (
            SELECT  project_id
            FROM    projects
            WHERE   client_id = :client_id
        );

85
আপনার এসকিউএল-তে IN কীওয়ার্ডটি ব্যবহার করা এড়াতে হবে (যদিও এটি প্রাথমিকভাবে বুঝতে সহজ হয়) এবং পরিবর্তে (যখন সম্ভব) যোগদান করুন, কারণ সাবকিউরিগুলি সাধারণত জিনিসগুলিকে অনেক ধীর করে তোলে।
ব্যবহারকারী 276648

14
সাব কোয়েরি দ্বারা বিপুল সংখ্যক সারি ফিরে আসার পরে এটি ডিবি ক্র্যাশ হয়। এটি অত্যন্ত ধীর।
রাজ

2
@ ইউকনডুড প্রকৃতপক্ষে "IN" 1 ম "যোগ" এর চেয়ে বোঝা অনেক সহজ, এবং সে কারণেই যারা এসকিউএল এর সাথে সত্যই পরিচিত নন তারা যে কোনও জায়গায় "IN" লেখা শেষ করবেন, যখন তারা "জোইন" ব্যবহার করতে পারবেন যা আরও ভাল পারফর্ম করে ( বা ক্যুয়ারীর উপর নির্ভর করে বেশ কিছু ভাল) আমার মনে আছে বেশ কয়েক বছর আগে, প্রায় আমার সমস্ত এসকিউএল ক্যোয়ারী এমন কেউ লিখেছিলেন যা আসলে ভাল জিজ্ঞাসা লিখতে জানত। এজন্য আমি "IN" এড়ানোর জন্য মন্তব্যটি যুক্ত করেছি, যাতে লোকেরা জানতে পারে যে যদি সম্ভব হয় তবে তাদের এটি ব্যবহার করা এড়ানো উচিত।
ব্যবহারকারী 276648

10
আমি এই পৃষ্ঠায় আসার খুব কারণ হ'ল একটি আইএন বিবৃতি দিয়ে আমি যে ক্যোয়ারী লিখেছি তা কুকুর ধীর ছিল। এখানে অবশ্যই গ্রহণযোগ্য উত্তর এড়িয়ে চলুন।
মাইককুলস

4
এই প্রশ্নটি যতটা পুরনো, আপনার কেন IN এর পরিবর্তে JOIN ব্যবহার করা উচিত তা জানা গুরুত্বপূর্ণ। যখন শর্তটি একটি সারিতে চলতে থাকে, তখন এটি সেই ক্যোয়ারী IN এর ভিতরে চালাচ্ছে। তার মানে, যদি এখানে 100 টি সারি রয়েছে যে যেখানে তার বিরুদ্ধে পরীক্ষা করা দরকার, সেই সাবকিউরিটি 100 বার চালানো হবে। যেখানে কোনও জোইন কেবলমাত্র চলবে। সুতরাং, আপনার ডিবিটি আরও বড় হতে শুরু করে, এই ক্যোয়ারীটি শেষ হতে আরও বেশি সময় নিতে চলেছে। @ মারকাস কেবল কারণ কোনও কিছু সমালোচিত নয় তার অর্থ এই নয় যে আপনার খারাপ কোডটি লেখা উচিত। কিছুটা আরও ভাল লিখে এটি ভবিষ্যতে আপনার অনেক সময় এবং মাথা ব্যথা সাশ্রয় করবে। :)
রাইজিংসুন

11

মাইএসকিউএল JOIN এর সাথে রেকর্ড মুছে দেয়

আপনি অন্যান্য টেবিলের সাথে সম্পর্কিত রেকর্ড রয়েছে এমন একটি টেবিল থেকে রেকর্ড নির্বাচন করতে আপনি নির্বাচন বয়ানটিতে সাধারণত অন্তর্ভুক্ত হন use আমরা কোনও টেবিল থেকে রেকর্ডগুলি মুছে ফেলতে এবং অন্য টেবিলে সম্পর্কিত রেকর্ডগুলি মুছে ফেলতে উদাহরণস্বরূপ, একটি নির্দিষ্ট শর্ত পূরণ করে উভয় টি 1 এবং টি 2 টেবিলের রেকর্ড মুছতে, মুছে ফেলার বিবরণ সহ অন্তর্ভুক্ত যোগ দারাটিও ব্যবহার করতে পারি, আপনি নীচের বিবৃতিটি ব্যবহার করুন:

DELETE T1, T2
FROM T1
INNER JOIN T2 ON T1.key = T2.key
WHERE condition

লক্ষ্য করুন যে আপনি টেবিলের নাম T1 এবং T2 ডিলেট এবং FROM এর মধ্যে রেখেছেন। আপনি যদি টি 1 টেবিলটি বাদ দেন, মোছা বিবৃতিটি কেবল টি 2 টেবিলের রেকর্ডগুলি মুছে ফেলবে এবং আপনি যদি টি 2 টেবিলটি বাদ দেন, কেবল টি 1 টেবিলের রেকর্ডগুলি মোছা হবে।

T1.key = T2.key যোগদানের শর্তটি টি 2 টেবিলের সাথে সম্পর্কিত রেকর্ডগুলি নির্দিষ্ট করে যা মুছতে হবে।

WHERE ধারাতে শর্তটি টি 1 এবং টি 2-তে কোন রেকর্ড মুছে ফেলা দরকার তা নির্দিষ্ট করে।


11

একক সারণী মুছুন:

postsটেবিল থেকে এন্ট্রি মুছতে :

DELETE ps 
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id;

projectsটেবিল থেকে এন্ট্রি মুছতে :

DELETE pj 
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id;

clientsটেবিল থেকে এন্ট্রি মুছতে :

DELETE C
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id;

একাধিক টেবিল মুছুন:

যোগদানের ফলাফলের বাইরে একাধিক টেবিল থেকে এন্ট্রি মুছে ফেলার জন্য আপনাকে DELETEকমা দ্বারা পৃথক করা তালিকা হিসাবে সারণীর নাম উল্লেখ করতে হবে :

ধরুন আপনি সব তিনটি টেবিল (থেকে এন্ট্রি মুছে ফেলতে চান posts, projects, clients) একটি নির্দিষ্ট ক্লায়েন্টের জন্য:

DELETE C,pj,ps 
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id


4

একটি উপ ব্যবহার মোছার আরেকটি পদ্ধতি নির্বাচন যে ব্যবহার বেশী ভালো INহবেWHERE EXISTS

DELETE  FROM posts
WHERE   EXISTS ( SELECT  1 
                 FROM    projects
                 WHERE   projects.client_id = posts.client_id);

পরিবর্তে যোগদানের এই ব্যবহার করতে একটি কারন হল একটি যে DELETEসঙ্গে JOINনিষেধের ব্যবহার LIMIT। আপনি যদি পুরো টেবিলের লকগুলি না তৈরি করতে চান তবে যদি আপনি ব্লকগুলিতে মুছতে চান তবে আপনি LIMITএই DELETE WHERE EXISTSপদ্ধতিটি ব্যবহার করতে পারেন ।


1
এই ক্যোয়ারী কি "এলিয়াস" দিয়ে লেখা যায়? এটির বাক্য গঠন থেকে খুব স্পষ্ট হয় না যে কীভাবে postsEXISTS () এর postsমধ্যে সারিগুলি মুছে ফেলা হয় একই রকম । (আইএমএইচওও হোক)
ম্যাটবিয়ানকো

আমি আপনাকে শুনছি, তবে টেবিলের এ্যালিয়াসগুলি মুছে ফেলার অনুমতি নেই। সাব ক্যোয়ারিতে থাকা "পোস্টগুলি" এর পুরো টেবিলের নাম থাকতে হবে, যার অর্থ আপনি যদি সেই টেবিলটি আপনার সাব-সিলেক্ট থেকে সাব-সিলেক্টে পুনরায় ব্যবহার করতে চান তবে আপনাকে এটির নাম রাখতে হবে।
জিম ক্লাউজ

1
এটি কাজ করে:DELETE p FROM posts p WHERE EXISTS ( SELECT 1 FROM projects WHERE projects.client_id = p.client_id);
ম্যাটবিয়ানকো

4
mysql> INSERT INTO tb1 VALUES(1,1),(2,2),(3,3),(6,60),(7,70),(8,80);

mysql> INSERT INTO tb2 VALUES(1,1),(2,2),(3,3),(4,40),(5,50),(9,90);

একটি টেবিল থেকে রেকর্ড মুছে দিন:

mysql> DELETE tb1 FROM tb1,tb2 WHERE tb1.id= tb2.id;

উভয় সারণী থেকে রেকর্ডস মুছে দিন:

mysql> DELETE tb2,tb1 FROM tb2 JOIN tb1 USING(id);

1

যদি যোগদান আপনার পক্ষে কাজ না করে আপনি এই সমাধানটি চেষ্টা করতে পারেন। এটি বিদেশী কী + যখন কোন শর্তের নির্দিষ্ট নয় ব্যবহার করার সময় টি 1 থেকে এতিম রেকর্ডগুলি মোছার জন্য। উদাহরণস্বরূপ, এটি টেবিল 1 থেকে রেকর্ডগুলি মুছে ফেলবে, এর ফাঁকা ক্ষেত্রের "কোড" রয়েছে এবং এতে টেবিল 2 তে রেকর্ড নেই, ফিল্ডের সাথে "নামের" সাথে মিল রয়েছে।

delete table1 from table1 t1 
    where  t1.code = '' 
    and 0=(select count(t2.name) from table2 t2 where t2.name=t1.name);

0

এটা চেষ্টা কর,

DELETE posts.*
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id

-3

- নোট করুন যে টেবিলটি যেখানে আপনার মুছতে হবে সেখানে আপনি কোনও উপনাম ব্যবহার করতে পারবেন না

DELETE tbl_pagos_activos_usuario
FROM tbl_pagos_activos_usuario, tbl_usuarios b, tbl_facturas c
Where tbl_pagos_activos_usuario.usuario=b.cedula
and tbl_pagos_activos_usuario.cod=c.cod
and tbl_pagos_activos_usuario.rif=c.identificador
and tbl_pagos_activos_usuario.usuario=c.pay_for
and tbl_pagos_activos_usuario.nconfppto=c.nconfppto
and NOT ISNULL(tbl_pagos_activos_usuario.nconfppto)
and c.estatus=50
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.