মাইএসকিউএল শর্ত হিসাবে subquery সঙ্গে মুছে ফেলা


87

আমি এই জাতীয় একটি কোয়েরি করার চেষ্টা করছি:

DELETE FROM term_hierarchy AS th
WHERE th.parent = 1015 AND th.tid IN (
    SELECT DISTINCT(th1.tid)
    FROM term_hierarchy AS th1
    INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015)
    WHERE th1.parent = 1015
);

আপনি সম্ভবত বলতে পারেন যে, একই জোয়ারের অন্য বাবা-মা থাকলে 1015 এর সাথে পিতামাতার সম্পর্ক মুছতে চাই। তবে, এটি আমার একটি সিনট্যাক্স ত্রুটি দেয়:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS th
WHERE th.parent = 1015 AND th.tid IN (
  SELECT DISTINCT(th1.tid)
  FROM ter' at line 1

আমি ডকুমেন্টেশন চেক করেছি, এবং নিজেই subquery চালানো, এবং এটি সব চেক আউট বলে মনে হচ্ছে। এখানে কি সমস্যা আছে তা কেউ বুঝতে পারেন?

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


4
দৃষ্টি আকর্ষণ করছি : নীচে ভাল উত্তর stackoverflow.com/a/4471359/956397 কেবল পর টেবিল ওরফে যোগDELETE t FROM table t ...
PiTheNumber

উত্তর:


40

আপনি মোছার জন্য লক্ষ্য সারণি নির্দিষ্ট করতে পারবেন না।

একটি workaround

create table term_hierarchy_backup (tid int(10)); <- check data type

insert into term_hierarchy_backup 
SELECT DISTINCT(th1.tid)
FROM term_hierarchy AS th1
INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015)
WHERE th1.parent = 1015;

DELETE FROM term_hierarchy AS th
WHERE th.parent = 1015 AND th.tid IN (select tid from term_hierarchy_backup);

আমরা উভয়ই ঠিক - নীচে আমার উত্তরে তার মন্তব্য দেখুন। এলিয়াস সিনট্যাক্স এবং লজিক উভয়ই বিষয় ছিল :)
জেএনকে

হ্যাঁ, সাব-কোয়ের মাধ্যমে মুছে ফেলা বর্তমানে মাইএসকিউএলে সম্ভব নয় - এটি একবার দেখার জন্য ধন্যবাদ :)
মিকল

এই শেষ লাইনে "ডার্মি হাইয়ারারকি এএস ডি" কে একই সমস্যা হয় না? আমি ওপির মতোই একটি সিনট্যাক্স ত্রুটি পেয়েছি।
মলহাল

আপনার পদ__পদ্ধতি_ব্যাকআপ.টিডে সূচি যুক্ত করা উচিত।
রোমান নেওয়াজা

4
আমি তা যাচাই করতে সক্ষম হয়েছি যে মারিয়াডিবি 10.3.14 বা মাইএসকিউএল কমিউনিটি সার্ভার 5.7.27
আলফাম

292

সাবকিউরিটি ব্যবহার করার সময় মুছতে চাইছেন এমন অন্যদের জন্য, আমি মাইএসকিউএলকে আউটসামার্ট করার জন্য এই উদাহরণটি রেখে যাই (এমনকি কিছু লোক মনে করে এটি সম্পন্ন করা যায় না):

DELETE e.*
FROM tableE e
WHERE id IN (SELECT id
             FROM tableE
             WHERE arg = 1 AND foo = 'bar');

আপনাকে একটি ত্রুটি দেবে:

ERROR 1093 (HY000): You can't specify target table 'e' for update in FROM clause

তবে এই প্রশ্নটি:

DELETE e.*
FROM tableE e
WHERE id IN (SELECT id
             FROM (SELECT id
                   FROM tableE
                   WHERE arg = 1 AND foo = 'bar') x);

ঠিক কাজ করবে:

Query OK, 1 row affected (3.91 sec)

আপনার সাবকিউরিটিকে একটি অতিরিক্ত সাবকোয়রিতে আবদ্ধ করুন (এখানে x নাম দেওয়া হয়েছে) এবং মাইএসকিউএল খুশি খুশি যা আপনি জিজ্ঞাসা করবেন।


10
কিছু সময় নিল তবে আমি তা কাজে লাগিয়েছি। গুরুত্বপূর্ণ: 1) প্রথম টেবিলটি অবশ্যই এখানে "ই" দিয়ে দেখানো হবে, 2) শেষে "এক্স" কোনও স্থানধারক নয়, এটি সাবকোয়ারির দ্বারা উত্পাদিত টেম্প টেবিলের জন্য উপনাম "(সারণী থেকে সারণি নির্বাচন করুন) যেখানে যুক্তি = 1 এবং foo = 'বার') "।
তিলমান হাউশার

4
কেন এই কাজ করে? এটি আমার জন্য অনেক পরিবর্তন করে, তবে আরও, এটি কাজ করা উচিত নয়। এটা তোলে করেন কাজ, কিন্তু এটা না করা উচিত।
donatJ

4
অবিশ্বাস্য. এটি আসলে কাজ করে! তবে আপনি টেবিলের সাথে ই-এর সাথে জোর করে বাধ্য হবেন না ... আপনি যে কোনও উপন্যাস চান তা ব্যবহার করতে পারেন।
আন্দ্রে সান্দুলসকু

4
@ জাকাবাদাম্বালজ আমার যুক্তিটি সামনে এলে যেটি ছিল "এস ইলেক্ট আইডি" দিয়ে শুরু করা সাবকিউরিটি শেষ হয় এবং আইডির একটি তালিকা ফেরত দেয় এবং তাই আপনি যে টেবিলটি মুছতে চান তার লকটি প্রকাশ করে।
কোডআলিপ

9
@ জাকাবাদাম্বালাজ: আমরা eএকটি মুছে ফেলতে এবং এর উপ-নির্বাচন করে একই টেবিলটি ব্যবহার করতে পারি না । আমরা করতে পারেন , তবে উপ-উপ-নির্বাচন একটি অস্থায়ী সারণী (তৈরি করতে ব্যবহার x), এবং ব্যবহার করে উপ-নির্বাচন জন্য।
স্টিভ আলমন্ড

40

উপন্যাসটি DELETEকীওয়ার্ডের পরে অন্তর্ভুক্ত করা উচিত :

DELETE th
FROM term_hierarchy AS th
WHERE th.parent = 1015 AND th.tid IN 
(
    SELECT DISTINCT(th1.tid)
    FROM term_hierarchy AS th1
    INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015)
    WHERE th1.parent = 1015
);

4
এটি একটি ভাল উত্তর। মূল পোস্টের মতো সমস্যাগুলি সমাধান করতে প্রপার অ্যালিয়াসিং দীর্ঘ পথ পাবে। (আমার মতো))
ইউসোমিও

11

মুছে ফেলার বিবরণীতে আপনাকে আবারও উপনামটি উল্লেখ করতে হবে, যেমন:

DELETE th FROM term_hierarchy AS th
....

মাইএসকিউএল ডক্সে এখানে বর্ণিত হিসাবে।


ওরফে সম্পর্কে নয়, দয়া করে আবারও ওপি পরীক্ষা করুন
আজ্রিয়াল

@ আজরিয়াল - আমি করেছি, এবং দয়া করে লক্ষ্য করুন যে ত্রুটিটি ওরফে সংজ্ঞা থেকে শুরু হয় এবং মাইএসকিউএল ডকুমেন্টেশনটি স্পষ্টভাবে জানিয়েছে যে আপনাকে ডিএলটিইটি বিবৃতিতে এবং এফআরএম ক্লজটিতে উপনামটি ব্যবহার করা দরকার। যদিও ডাউনটোটের জন্য ধন্যবাদ।
জেএনকে

কেবল এই কাজ delete from your_table as t1 where t1.id in(select t2.id from your_table t2);কি আপনি পেতে পারি?
আজ্রিয়াল

4
ডকুমেন্টেশন পরিষ্কারভাবে বলে; Currently, you cannot delete from a table and select from the same table in a subquery. dev.mysql.com/doc/refman/5.5/en/delete.html
Björn

4
আপনাকে উপনামটি ঠিক করতে হবে না, মুছতে নির্বাচন করার জন্য কেবলমাত্র লক্ষ্য সারণি নির্দিষ্ট করবেন না ... এটিই আসল সমস্যা
আজ্রিয়াল

7

আমি এটি কিছুটা ভিন্ন উপায়ে পৌঁছেছি এবং এটি আমার পক্ষে কাজ করেছে;

আমাকে secure_linksআমার টেবিল থেকে সরিয়ে ফেলতে হবে যা সেই টেবিলটিকে রেফারেন্স করেছে conditionsযেখানে কোনও শর্ত সারি আর নেই। মূলত একটি গৃহকর্মের স্ক্রিপ্ট। এটি আমাকে ত্রুটি দিয়েছে - আপনি মোছার জন্য লক্ষ্য সারণি নির্দিষ্ট করতে পারবেন না।

অনুপ্রেরণার জন্য এখানে খুঁজছি আমি নীচের ক্যোয়ারী নিয়ে এসেছি এবং এটি ঠিক কাজ করে। এটি কারণ এটি একটি অস্থায়ী সারণী তৈরি করে যা sl1ডিলিটের জন্য রেফারেন্স হিসাবে ব্যবহৃত হয়।

DELETE FROM `secure_links` WHERE `secure_links`.`link_id` IN 
            (
            SELECT
                `sl1`.`link_id` 
            FROM 
                (
                SELECT 

                    `sl2`.`link_id` 

                FROM 
                    `secure_links` AS `sl2` 
                    LEFT JOIN `conditions` ON `conditions`.`job` = `sl2`.`job` 

                WHERE 

                    `sl2`.`action` = 'something' AND 
                    `conditions`.`ref` IS NULL 
                ) AS `sl1`
            )

আমার জন্য কাজ কর.


উপরের কোড কোডটি থেকে একটিটির সদৃশ ... ভাল কল থো ...;)
jrypkahauer

5

মুছে ফেলার "ইন" ধারাটি কি নয় ... যেখানে চূড়ান্তভাবে অক্ষম, সেখানে যদি সাবকোয়ারি থেকে বিপুল সংখ্যক মান ফিরে আসে? নিশ্চিত না যে আপনি কেবল "অভ্যন্তরীণ (উপবিজ্ঞান") এর চেয়ে আপনি কেবল অভ্যন্তরীণ (বা ডানদিকে) মুছে ফেলার জন্য আইডিতে থাকা সাবকোয়ারি থেকে মূল টেবিলের বিপরীতে কেন যোগ দিবেন না? "

DELETE T FROM Target AS T
RIGHT JOIN (full subquery already listed for the in() clause in answers above) ` AS TT ON (TT.ID = T.ID)

এবং এটির "মাইএসকিউএল এটি অনুমোদন দেয় না" তে উত্তর দেওয়া হয়েছে, তবে এটি আমার পক্ষে ঠিক কাজ করছে আমি সরবরাহ করে আমি কী মুছতে হবে তা পুরোপুরি পরিষ্কার করে দেওয়ার বিষয়টি নিশ্চিত করেছি (টি থেকে লক্ষ্যমাত্রা টি মুছে ফেলুন)। মাইএসকিউএল এ যোগদানের সাথে মুছুন মুছে ফেলুন / যোগ করুন ইস্যুটি স্পষ্ট করে।


2

আপনি যদি 2 টি প্রশ্নের সাথে এটি করতে চান তবে আপনি সর্বদা এর মতো কিছু করতে পারেন:

1) এর সাথে টেবিল থেকে আইডিগুলি ধরুন:

SELECT group_concat(id) as csv_result FROM your_table WHERE whatever = 'test' ...

তারপরে মাউস / কীবোর্ড বা প্রোগ্রামিং ভাষার সাথে ফলাফলটি নীচে XXX এ অনুলিপি করুন:

2) DELETE FROM your_table WHERE id IN ( XXX )

হতে পারে আপনি একটি ক্যোয়ারিতে এটি করতে পারেন, তবে এটি আমি পছন্দ করি।


0

@ কোডেরিপার, @ বেনিহিল: এটি প্রত্যাশার মতো কাজ করে।

তবে, আমি টেবিলে কয়েক মিলিয়ন সারি থাকার সময়ের জটিলতাটি অবাক করে দিচ্ছি? স্পষ্টতই, 5msসঠিকভাবে ইনডেক্স করা টেবিলটিতে 5 কে রেকর্ড থাকার জন্য এটি কার্যকর করতে প্রায় লেগেছিল ।

আমার প্রশ্ন:

SET status = '1'
WHERE id IN (
    SELECT id
    FROM (
      SELECT c2.id FROM clusters as c2
      WHERE c2.assign_to_user_id IS NOT NULL
        AND c2.id NOT IN (
         SELECT c1.id FROM clusters AS c1
           LEFT JOIN cluster_flags as cf on c1.last_flag_id = cf.id
           LEFT JOIN flag_types as ft on ft.id = cf.flag_type_id
         WHERE ft.slug = 'closed'
         )
      ) x)```

Or is there something we can improve on my query above?

0

আপনি মুছে ফেলার বিবরণীতে এইভাবে উপনামটি ব্যবহার করতে পারেন

DELETE  th.*
FROM term_hierarchy th
INNER JOIN term_hierarchy th2 ON (th1.tid = th2.tid AND th2.parent != 1015)
WHERE th.parent = 1015;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.