মাইএসকিউএল ত্রুটি 1093 - FROM ধারাটিতে আপডেটের জন্য লক্ষ্য সারণি নির্দিষ্ট করতে পারে না


591

আমার একটা টেবিল আছে story_categoryআমার ডেটাবেজে রয়েছে দুর্নীতিগ্রস্ত এন্ট্রি সহ। পরবর্তী ক্যোয়ারী দূষিত এন্ট্রিগুলি প্রদান করে:

SELECT * 
FROM  story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN 
       story_category ON category_id=category.id);

আমি তাদের নির্বাহ করে মুছে ফেলার চেষ্টা করেছি:

DELETE FROM story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category 
      INNER JOIN story_category ON category_id=category.id);

তবে আমি পরবর্তী ত্রুটি পেয়েছি:

# 1093 - আপনি এফআরওএম ক্লজটিতে আপডেটের জন্য টার্গেট টেবিল 'গল্প_শ্রেণী' নির্দিষ্ট করতে পারবেন না

আমি কীভাবে এটি কাটিয়ে উঠতে পারি?



2
মাইএসকিউএল বাগ ট্র্যাকারের বৈশিষ্ট্যটির অনুরোধটি এখানে উপস্থিত রয়েছে বলে মনে হচ্ছে: কোনও টেবিল আপডেট করতে পারবেন না এবং একটি উপকোয়ায় একই টেবিল থেকে নির্বাচন করতে পারবেন না
বেন

উত্তর:


713

আপডেট: এই উত্তরটি সাধারণ ত্রুটির শ্রেণিবিন্যাসকে কভার করে। ওপি-র সঠিক জিজ্ঞাসাটি কীভাবে সেরাভাবে পরিচালনা করা যায় সে সম্পর্কে আরও নির্দিষ্ট উত্তরের জন্য, দয়া করে এই প্রশ্নের অন্যান্য উত্তরগুলি দেখুন answers

মাইএসকিউএল এ আপনি নির্বাচন করুন অংশটি একই টেবিলটি পরিবর্তন করতে পারবেন না।
এই আচরণটি এখানে নথিভুক্ত করা হয়: http://dev.mysql.com/doc/refman/5.6/en/update.html

হতে পারে আপনি কেবল নিজেরাই টেবিলটিতে যোগ দিতে পারেন

যদি যুক্তিটি কোয়েরিকে পুনরায় আকার দেওয়ার পক্ষে যথেষ্ট সহজ হয় তবে সাব-কোয়েরিটি হারাবেন এবং উপযুক্ত নির্বাচনের মানদণ্ডকে নিয়োগ করে নিজেই টেবিলে যোগ দিন। এর ফলে মাইএসকিউএলটি টেবিলটিকে দুটি ভিন্ন জিনিস হিসাবে দেখাবে এবং ধ্বংসাত্মক পরিবর্তনগুলি এগিয়ে যাওয়ার অনুমতি দেবে।

UPDATE tbl AS a
INNER JOIN tbl AS b ON ....
SET a.col = b.col

বিকল্পভাবে, ধারাটি থেকে সাবকোয়ারিকে আরও গভীরভাবে বাসাতে চেষ্টা করুন ...

আপনার যদি একেবারে সাবকোয়ারির প্রয়োজন হয় তবে একটি কার্যকারিতা রয়েছে, তবে এটি পারফরম্যান্স সহ বেশ কয়েকটি কারণে কুৎসিত:

UPDATE tbl SET col = (
  SELECT ... FROM (SELECT.... FROM) AS x);

এফআরএম ক্লজে নেস্টেড সাবকোয়ারি একটি অন্তর্নিহিত অস্থায়ী টেবিল তৈরি করে , তাই এটি আপনি যে আপডেট করছেন তা একই টেবিল হিসাবে গণ্য হবে না।

... তবে ক্যোয়ারী অপটিমাইজারের দিকে নজর রাখুন

তবে, সাবধান থাকুন যে মাইএসকিউএল ৫..6..6 এবং এর পরের থেকে, অপটিমাইজার সাবউয়েরিটি অপ্টিমাইজ করতে পারে এবং তবুও আপনাকে ত্রুটি দেয়। ভাগ্যক্রমে, optimizer_switchপরিবর্তনগুলি এই আচরণটি বন্ধ করতে ব্যবহার করা যেতে পারে; যদিও আমি স্বল্পমেয়াদী সংশোধন বা ছোট এক-কাজের জন্য আরও কিছু হিসাবে এটি করার পরামর্শ দিতে পারি না।

SET optimizer_switch = 'derived_merge=off';

মন্তব্যগুলিতে এই পরামর্শের জন্য পিটার ভি। মার্চকে ধন্যবাদ ।

উদাহরণ কৌশলটি ব্যারন শোয়ার্জ থেকে ছিল, যা মূলত নাবলে প্রকাশিত হয়েছিল , এখানে প্যারাফ্রেসড এবং প্রসারিত।


1
এই উত্তরটি অগ্রাহ্য করা হয়েছে কারণ আমি আইটেমগুলি মুছতে হয়েছিল এবং অন্য টেবিল থেকে তথ্য পেতে পারি না, একই টেবিল থেকে সাবকোয়ারি করতে হয়েছিল। যেহেতু ত্রুটিটি গুগল করার সময় এটিই শীর্ষে উঠে আসে তা আমার পক্ষে এবং একই টেবিলটি থেকে সাবকিরিয়িংয়ের সময় প্রচুর লোক আপডেট করার চেষ্টা করে যা আমার পক্ষে সেরা ফিট answer
এইচএমআর

2
@ চেকিসফট, পরিবর্তে পরিবর্তিত মানগুলিতে কেন সংরক্ষণ করবেন না?
পেসারিয়ার

19
সাবধান, মাইএসকিউএল 5..7. from থেকে , অপ্টিমাইজার উপ-কোয়েরিটিকে অপ্টিমাইজ করতে পারে এবং তবুও আপনাকে ত্রুটিটি দিতে পারে, যদি না আপনি SET optimizer_switch = 'derived_merge=off';:-(
পিটার ভি।

1
@ পিটারভি.মার্চ mysqlserverteam.com/derived-tables-in-mysql-5-7 অনুসরণ করছেন , যদি কিছু নির্দিষ্ট অপারেশন পরিচালিত হয় তবে একত্রিত হতে পারে না। উদাহরণস্বরূপ, একটি সীমাবদ্ধতার সাথে উদ্ভাবিত ডামি টেবিল সরবরাহ করে (অনন্যতাকে) এবং ত্রুটি কখনই ঘটবে না। যদিও এটি বেশ হ্যাকিশ এবং এখনও ঝুঁকি রয়েছে যে মাইএসকিউএল এর ভবিষ্যতের সংস্করণগুলি লিমিটেডের সাথে মিলিত অনুসন্ধানগুলিকে সর্বোপরি সমর্থন করবে।
ব্যবহারকারী 2180613

আপনি, দয়া করে, এই কর্মক্ষেত্র সম্পর্কে একটি সম্পূর্ণ উদাহরণ প্রদান করতে পারেন? আপডেট করুন tbl SET কল = (নির্বাচন করুন ... থেকে নির্বাচন করুন (নির্বাচন করুন .... থেকে এক্স)); আমি এখনও ত্রুটি
পাচ্ছি

310

NexusRex একটি খুব ভাল সমাধান সরবরাহ করেছে একই টেবিল থেকে যোগদানের সঙ্গে মুছে ফেলার জন্য।

আপনি যদি এটি করেন:

DELETE FROM story_category
WHERE category_id NOT IN (
        SELECT DISTINCT category.id AS cid FROM category 
        INNER JOIN story_category ON category_id=category.id
)

আপনি একটি ত্রুটি পেতে চলেছেন।

তবে আপনি যদি শর্তটি আরও একটিতে জড়ান তবে এটি নির্বাচন করুন:

DELETE FROM story_category
WHERE category_id NOT IN (
    SELECT cid FROM (
        SELECT DISTINCT category.id AS cid FROM category 
        INNER JOIN story_category ON category_id=category.id
    ) AS c
)

এটা সঠিক জিনিস করতে হবে !!

ব্যাখ্যা: ক্যোয়ারী অপ্টিমাইজারটি প্রথম ক্যোয়ারির জন্য ডার্কড মার্জ অপ্টিমাইজেশন করে (যার ফলে এটি ত্রুটির সাথে ব্যর্থ হয়), তবে দ্বিতীয় ক্যোয়ারী প্রাপ্ত হওয়া মার্জ অপটিমাইজেশনের জন্য যোগ্য নয় । অতএব অপ্টিমাইজারটি প্রথমে সাবকোয়ারিটি কার্যকর করতে বাধ্য হয়।


6
সম্ভবত এটি কারণ যে আমি আজকে আবদ্ধ অবস্থায় আছি তবে এটি সবচেয়ে সহজ উত্তর ছিল, যদিও এটি সম্ভবত "সেরা" নাও হয়।
টাইলার ভি।

4
এটি দুর্দান্ত কাজ করেছে, ধন্যবাদ! তাহলে এখানে যুক্তি কী? যদি এটি আরও একটি স্তর বাসাতে থাকে তবে এটি বাহ্যিক অংশের আগেই কার্যকর করা হবে? এবং যদি এটি নেস্টেড না থাকে তবে মাইএসকিউএল এটি মুছে ফেলার পরে টেবিলটিতে একটি লক থাকার পরে চেষ্টা করে?
ফ্ল্যাট বিড়াল

43
এই ত্রুটি এবং সমাধানটি কোনও যৌক্তিক ধারণা দেয় না ... তবে এটি কার্যকর হয়। কখনও কখনও আমি ভাবছি যে মাইএসকিউএল ডেভসগুলি কী ড্রাগগুলি রয়েছে ...
সেরিন

1
@ কেরিনের সাথে সম্মত হন .. এটি সম্পূর্ণ অযৌক্তিক, তবে এটি কার্যকর।
ফাস্টট্র্যাক

@ আইকনোভাল সমাধানের জন্য আপনাকে ধন্যবাদ তবে এটি আমার পক্ষে ন্যূনতম অর্থবোধ করে না, দেখে মনে হচ্ছে আপনি মাইএসকিউএলকে বোকা বানাচ্ছেন এবং তিনি তা গ্রহণ করেছেন, লোল
ডিফ্রেটিস

106

inner joinআপনার উপ-ক্যোয়ারীতে অপ্রয়োজনীয়। দেখে মনে হচ্ছে আপনি এন্ট্রিগুলির মুছে ফেলতে চান story_categoryযেখানে category_idনেই categoryটেবিল।

এটা কর:

DELETE FROM story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category);

ঐটার পরিবর্তে:

DELETE FROM story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN
         story_category ON category_id=category.id);

5
এটি শীর্ষ উত্তর হতে হবে! সম্ভবত প্রথম "এর পরিবর্তে" মুছুন।
hoyhoy

1
আমি মনে করি DISTINCTএখানে অপ্রয়োজনীয় - উন্নত পারফরম্যান্সের জন্য;)।
shA.t

1
আমি অবশ্যই পাগল হই উত্তরটি মূল হিসাবে যা বলা হয়েছিল ঠিক একইভাবে।
জেফ লোরি

এটি আমার জন্যও উত্তর। না where inতাই আপনি প্রাথমিক টেবিল subquery দিতে হবে না, আইডি কলামে।
রিচার্ড

@ জেফলওয়ারি - প্রথম কোড ব্লকের উত্তর এখানে; এটি দ্বিতীয় কোড ব্লক যা প্রশ্ন থেকে।
টুলমেকারস্টেভ

95

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

UPDATE skills AS s, (SELECT id  FROM skills WHERE type = 'Programming') AS p
SET s.type = 'Development' 
WHERE s.id = p.id;

11
এটি কি শুধু হিসাবে লেখা যায় না UPDATE skills SET type='Development' WHERE type='Programming';? এটি আসল প্রশ্নের উত্তর দিবে বলে মনে হয় না।
লিলবির্ডি

1
ওভারকিলের মতো দেখে মনে হচ্ছে, @ লিলবির্ডি সঠিক - এটি কেবল হতে পারে UPDATE skills SET type='Development' WHERE type='Programming';। আমি বুঝতে পারি না কেন এত লোক কেন তারা যা করে তা নিয়ে চিন্তা করে না ...
shaydyx

1
এটি এখানে সেরা উত্তর, আইএমএইচও। এটি সিনট্যাক্সটি বোঝা সহজ, আপনি আপনার আগের বিবৃতিটি পুনরায় ব্যবহার করতে পারেন এবং এটি কিছু সুপার সুনির্দিষ্ট ক্ষেত্রে সীমাবদ্ধ নয়।
স্টিফেন উইঙ্কলার 14

2
উদাহরণস্বরূপ মামলাটি প্রশ্নবিদ্ধ হলেও, বাস্তব-বিশ্বের পরিস্থিতিগুলিতে নীতিটি বোঝা ও স্থাপন করা ভাল। প্রদর্শিত জিজ্ঞাসাটি কাজ করে কারণ টেবিল তালিকার অন্তর্নিহিত যোগদান সাব-কোয়েরির জন্য একটি অস্থায়ী টেবিল তৈরি করে, এইভাবে স্থিতিশীল ফলাফল সরবরাহ করে এবং একই টেবিলটির পুনরুদ্ধার এবং পরিবর্তনের মধ্যে সংঘর্ষ এড়ানো যায়।
AnrDaemon

1
এটি অতিরিক্ত ওভারকিল হওয়ার বিষয়ে কেউ কী বলতে পারে তা নির্বিশেষে এটি শিরোনামের শর্তে প্রশ্নের উত্তর দেয়।
নেপিত

35
DELETE FROM story_category
WHERE category_id NOT IN (
    SELECT cid FROM (
        SELECT DISTINCT category.id AS cid FROM category INNER JOIN story_category ON category_id=category.id
    ) AS c
)

3
আপনি কেন ব্যাখ্যা করতে পারেন যে এটি কেন কাজ করে, কেন কেবল বাসা বাঁধে আরও একটি স্তর কাজ করে? এই প্রশ্নটি ইতিমধ্যে @ একো নোভালের প্রশ্নের মন্তব্য হিসাবে জিজ্ঞাসা করা হয়েছে তবে কেউ প্রতিক্রিয়া জানায় না। আপনি সাহায্য করতে পারেন।
অক্ষয় অরোরা

@ অক্ষয়আরোরা, @ চেকিসফ্টের উত্তরে 'সম্ভবত আপনি কেবল নিজেরাই টেবিলে যোগ দিতে পারেন' শিরোনামের অংশটি নিয়ে যান। তিনি বলেছিলেন UPDATE tbl AS a INNER JOIN tbl AS b ON .... SET a.col = b.col- এটি এখানে একই টেবিলের জন্য আলাদা আলাদা উপন্যাস হিসাবে ব্যবহৃত হবে। একইভাবে @ নেক্সাসআরেক্সের উত্তরে প্রথম SELECTক্যোয়ারী উত্পন্ন টেবিল হিসাবে কাজ করে যা story_categoryদ্বিতীয়বার ব্যবহার করা হয়। ওপিতে উল্লিখিত ত্রুটিটি এখানে সংঘটিত হওয়া উচিত নয়, তাই না?
ইসতিয়াক আহমেদ

31

আপনি যদি না করতে পারেন

UPDATE table SET a=value WHERE x IN
    (SELECT x FROM table WHERE condition);

কারণ এটি একই টেবিল, আপনি কৌশল এবং করতে পারেন:

UPDATE table SET a=value WHERE x IN
    (SELECT * FROM (SELECT x FROM table WHERE condition) as t)

[আপডেট বা মুছুন বা যাই হোক না কেন]


উপরের সমস্ত উত্তরগুলির সবচেয়ে বোধগম্য এবং যৌক্তিক বাস্তবায়ন। সহজ এবং যথাযথ.
ক্লেইন ডিসিলভা

এটি এখন আমার কর্মপ্রবাহের অংশে পরিণত হয়েছে। এই ত্রুটিটিতে আটকে যান, এই উত্তরের দিকে যান এবং কোয়েরিটি সংশোধন করুন। ধন্যবাদ।
বৈভব

13

কোনও টেবিলে> = 1 থাকলে অগ্রাধিকার কলাম মানটি 1 দ্বারা আপডেট করার জন্য আমি এটি করেছি এবং কমপক্ষে একটি সারিটিতে অগ্রাধিকার = 1 রয়েছে কিনা তা নিশ্চিত করার জন্য একই টেবিলের সাব-কোয়েরি ব্যবহার করে তার ক্লজটিতে এটি করা হয়েছে because আপডেট করার সময় শর্তটি পরীক্ষা করা উচিত):


UPDATE My_Table
SET Priority=Priority + 1
WHERE Priority >= 1
AND (SELECT TRUE FROM (SELECT * FROM My_Table WHERE Priority=1 LIMIT 1) as t);

আমি জানি এটি কিছুটা কুরুচিপূর্ণ তবে এটি কার্যকর কাজ করে।


1
@ বেনাম_আরউভিউয়ার: কারও মন্তব্যে [-1] বা এমনকি [+1] দেওয়ার ক্ষেত্রে দয়া করে আপনি কেন এটি দিয়েছেন তা উল্লেখ করুন। ধন্যবাদ !!!
স্যাটিউ করুন

1
-1 কারণ এটি ভুল। আপনি নির্বাচনী বিবৃতিতে যে একই টেবিলটি ব্যবহার করেন আপনি তা পরিবর্তন করতে পারবেন না।
ক্রিস

1
@ চিরিস আমি এটি মাইএসকিউএলে যাচাই করেছি এবং এটি আমার পক্ষে ঠিক কাজ করে তাই আমি আপনাকে অনুরোধ করব আপনার দয়া করে এটি শেষে যাচাই করুন এবং তারপরে এটি সঠিক বা ভুল হিসাবে দাবি করুন। ধন্যবাদ !!!
পরিত্যক্ত

1
এই পৃষ্ঠার নীচে এটি বলে যে 'বর্তমানে, আপনি কোনও টেবিল আপডেট করতে পারবেন না এবং একটি উপ-বিভাগে একই টেবিল থেকে নির্বাচন করতে পারবেন না।' - এবং আমি অনেক সময় এটি সত্য হতে পেরেছি। dev.mysql.com/doc/refman/5.0/en/update.html
ক্রিস

19
@ ক্রিস আমি জানি যে, তবে এটির জন্য একটি কার্যকর পরিকল্পনা রয়েছে এবং এটি আমার 'আপডেট' প্রশ্নের সাথে দেখাতে চেষ্টা করেছি এবং বিশ্বাস করি এটি ঠিক কাজ করে believe আমি মনে করি না আপনি সত্যিই আমার জিজ্ঞাসাটি যাচাই করার চেষ্টা করেছেন।
11'13

6

এটি করার সহজতম উপায় হ'ল আপনি যখন সাব কোয়েরির ভিতরে প্যারেন্ট ক্যোয়ারী টেবিলটি উল্লেখ করছেন তখন একটি টেবিলের নাম ব্যবহার করুন।

উদাহরণ:

insert into xxx_tab (trans_id) values ((select max(trans_id)+1 from xxx_tab));

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

insert into xxx_tab (trans_id) values ((select max(P.trans_id)+1 from xxx_tab P));

5

আপনি কোনও টেম্প টেবিলের মধ্যে কাঙ্ক্ষিত সারিগুলির আইডিগুলি sertোকাতে এবং তারপরে সেই সারণীতে পাওয়া সমস্ত সারি মুছে ফেলতে পারেন।

যা হতে পারে @ শেইকসোফট বলতে এটি দুটি পদক্ষেপের মাধ্যমে বোঝায়।


3

মতে মাইএসকিউএল আপডেট সিনট্যাক্স @CheekySoft দ্বারা সংযুক্ত, এটা ঠিক নীচে বলেছেন।

বর্তমানে, আপনি কোনও টেবিল আপডেট করতে পারবেন না এবং একটি সাব-কোয়েরিতে একই টেবিল থেকে নির্বাচন করতে পারবেন না।

আমার ধারণা আপনি ইউনিয়ন থেকে এখনও এটি নির্বাচন করার সময় স্টোর_শ্রেণী থেকে মুছে ফেলছেন।


3

ওপি যে সুনির্দিষ্ট ক্যোয়ারীটি অর্জন করার চেষ্টা করছে তার জন্য আদর্শ ও সবচেয়ে কার্যকর উপায়টি হ'ল কোনও সাবকিউরিটি ব্যবহার না করা।

LEFT JOINওপি'র দুটি প্রশ্নের সংস্করণ এখানে রয়েছে :

SELECT s.* 
FROM story_category s 
LEFT JOIN category c 
ON c.id=s.category_id 
WHERE c.id IS NULL;

দ্রষ্টব্য: সারণীতে DELETE sমুছে ফেলা অপারেশনগুলি সীমাবদ্ধ করে story_category
নথিপত্র

DELETE s 
FROM story_category s 
LEFT JOIN category c 
ON c.id=s.category_id 
WHERE c.id IS NULL;

1
আশ্চর্যরূপে এর আরও বেশি ভোট নেই। এটিও লক্ষ করা উচিত যে মাল্টি-টেবিল সিনট্যাক্সও UPDATEবিবৃতি নিয়ে কাজ করে এবং সাব-কোয়েরিতে যোগ দেয় joined অনেকগুলি ব্যবহারের ক্ষেত্রে প্রয়োগটি কার্যকর করার জন্য আপনাকে LEFT JOIN ( SELECT ... )বিপরীতে সম্পাদন করার অনুমতি দিচ্ছে WHERE IN( SELECT ... )
fyrye

2

সামনের দরজা দিয়ে যখন কিছু কাজ না করে, তবে পিছনের দরজাটি ধরুন:

drop table if exists apples;
create table if not exists apples(variety char(10) primary key, price int);

insert into apples values('fuji', 5), ('gala', 6);

drop table if exists apples_new;
create table if not exists apples_new like apples;
insert into apples_new select * from apples;

update apples_new
    set price = (select price from apples where variety = 'gala')
    where variety = 'fuji';
rename table apples to apples_orig;
rename table apples_new to apples;
drop table apples_orig;

এটা দ্রুত. যত বড় ডেটা, তত ভাল।


11
এবং আপনি সবেমাত্র আপনার সমস্ত বিদেশী কী হারিয়েছেন এবং সম্ভবত আপনার কিছু ক্যাসকেডিং মোছাও রয়েছে।
ওয়াল্ফ

2

পৃথক ভেরিয়েবলে সিলেক্ট স্টেটমেন্টের ফলাফল সংরক্ষণের চেষ্টা করুন এবং তারপরে ক্যোয়ারি মুছতে এটি ব্যবহার করুন।



1

কিভাবে এই ক্যোয়ারী আশা করি এটি সাহায্য করবে

DELETE FROM story_category LEFT JOIN (SELECT category.id FROM category) cat ON story_category.id = cat.id WHERE cat.id IS NULL

ফলাফলটি দেখায়: '# 1064 - আপনার এসকিউএল সিনট্যাক্সে আপনার একটি ত্রুটি রয়েছে; 'লেফট জোইন (বিভাগ থেকে ফটোগুলি.শ্রেণীতে নির্বাচন করুন) বিড়াল' ক্যাট স্টোর-ক্যাটাগরী.আইডি = বিড়ালের কাছাকাছি ব্যবহার করতে ডান সিনট্যাক্সের জন্য আপনার মারিয়াডিবি সার্ভার সংস্করণের সাথে সম্পর্কিত ম্যানুয়ালটি পরীক্ষা করুন ' লাইনে 1 '
ইসতিয়াক আহমেদ

মাল্টি-টেবিল মোছার ব্যবহার করার সময় আপনাকে অবশ্যই আক্রান্ত টেবিলগুলি নির্দিষ্ট করতে হবে। DELETE story_category FROM ...যাইহোক, যোগদান করা সাব-কোয়েরিটি এই প্রসঙ্গে প্রয়োজনীয় নয় এবং এটি ব্যবহার করে সম্পাদন করা যেতে পারে LEFT JOIN category AS cat ON cat.id = story_category.category_id WHERE cat.id IS NULL, উত্তরে সঠিকভাবে উল্লেখের সাথে যুক্ত হওয়ার মানদণ্ডটি নোট করুনstory_category.id = cat.id
fyrye

0

যতটা উদ্বেগের দিক থেকে, আপনি সারিগুলি সরাতে চান story_categoryযেগুলি বিদ্যমান নেই category

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

SELECT * 
FROM  story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN 
       story_category ON category_id=category.id
);

মিশ্রন NOT INএকটি subquery যে সঙ্গে JOINগুলি মূল টেবিল unecessarily সংবর্ত মনে। এটি আরও একটি সরাসরি-ফরোয়ার্ড পদ্ধতিতে প্রকাশ করা যেতে পারে not existsএবং একটি সম্পর্কিত সম্পর্কযুক্ত সাবকোয়ারির সাথে:

select sc.*
from story_category sc
where not exists (select 1 from category c where c.id = sc.category_id);

এখন এটিকে কোনও deleteবিবৃতিতে পরিণত করা সহজ :

delete from story_category
where not exists (select 1 from category c where c.id = story_category.category_id);    

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

ডিবি ফিডেলে ডেমো :

-- set-up
create table story_category(category_id int);
create table category (id int);
insert into story_category values (1), (2), (3), (4), (5);
insert into category values (4), (5), (6), (7);

-- your original query to identify offending rows
SELECT * 
FROM  story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN 
       story_category ON category_id=category.id);
| বিভাগ_আইডি |
| ----------: |
| 1 |
| 2 |
| 3 |
-- a functionally-equivalent, simpler query for this
select sc.*
from story_category sc
where not exists (select 1 from category c where c.id = sc.category_id)
| বিভাগ_আইডি |
| ----------: |
| 1 |
| 2 |
| 3 |
-- the delete query
delete from story_category
where not exists (select 1 from category c where c.id = story_category.category_id);

-- outcome
select * from story_category;
| বিভাগ_আইডি |
| ----------: |
| 4 |
| 5 |
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.