আপনি যদি এখনও পর্যন্ত উত্তরগুলি একসাথে রেখে, পরিষ্কার এবং উন্নত করেন তবে আপনি এই উচ্চতর ক্যোয়ারিতে পৌঁছে যাবেন:
UPDATE sales
SET status = 'ACTIVE'
WHERE (saleprice, saledate) IN (
SELECT saleprice, saledate
FROM sales
GROUP BY saleprice, saledate
HAVING count(*) = 1
);
যা অনেক বেশি তাদের উভয়ের তুলনায় দ্রুত। 10 - 15 ফ্যাক্টর (পোস্টগ্র্রেএসকিউএল 8.4 এবং 9.1 এ আমার পরীক্ষাগুলিতে) বর্তমানে গৃহীত উত্তরের জন্য পারফরম্যান্সকে অনুগ্রহ করে।
তবে এটি এখনও সর্বোত্তম থেকে অনেক দূরে। NOT EXISTS
আরও ভাল পারফরম্যান্সের জন্য একটি (অ্যান্টি-) আধা-যুক্ত ব্যবহার করুন। EXISTS
স্ট্যান্ডার্ড এসকিউএল, সর্বদা চিরকাল ছিল (কমপক্ষে পোস্টগ্র্যাস এসকিউএল .2.২ থেকে এই প্রশ্নটি জিজ্ঞাসা করার অনেক আগে) এবং উপস্থাপিত প্রয়োজনীয়তাগুলি পুরোপুরি ফিট করে:
UPDATE sales s
SET status = 'ACTIVE'
WHERE NOT EXISTS (
SELECT FROM sales s1 -- SELECT list can be empty for EXISTS
WHERE s.saleprice = s1.saleprice
AND s.saledate = s1.saledate
AND s.id <> s1.id -- except for row itself
)
AND s.status IS DISTINCT FROM 'ACTIVE'; -- avoid empty updates. see below
ডিবি <> ফিডল এখানে
পুরানো এসকিউএল ফিডল
সারি সনাক্তকরণের জন্য অনন্য কী key
টেবিলের জন্য আপনার কাছে প্রাথমিক বা অনন্য কী না থাকলে ( id
উদাহরণস্বরূপ) আপনি ctid
এই ক্যোয়ারির উদ্দেশ্যে (তবে কিছু অন্যান্য উদ্দেশ্যে নয়) সিস্টেম কলামের বিকল্প নিতে পারেন :
AND s1.ctid <> s.ctid
প্রতিটি টেবিলের একটি প্রাথমিক কী থাকা উচিত। আপনার যদি না থাকে তবে একটি যুক্ত করুন। আমি একটি serial
বা একটি পরামর্শIDENTITY
পোস্টগ্রিস 10+ এ কলাম ।
সম্পর্কিত:
এটা কিভাবে দ্রুত?
EXISTS
অ্যান্টি-সেমি- জয়েন্টের সাবকিউরিটি প্রথম ডুপটি পাওয়া মাত্রই মূল্যায়ন করা বন্ধ করতে পারে (আরও দেখার পক্ষে কোনও অর্থ নেই)। কয়েকটি অনুলিপি সহ বেস টেবিলের জন্য এটি কেবলমাত্র হালকাভাবে আরও দক্ষ। সদৃশ প্রচুর সঙ্গে এই হয়ে উপায় আরও দক্ষ।
খালি আপডেটগুলি বাদ দিন
ইতিমধ্যে status = 'ACTIVE'
এই আপডেট থাকা সারিগুলির জন্য কোনও পরিবর্তন হবে না, তবে এখনও সম্পূর্ণ ব্যয়ে একটি নতুন সারি সংস্করণ প্রবেশ করান (ছোট ব্যতিক্রমগুলি প্রয়োগ হবে) apply সাধারণত, আপনি এটি চান না। WHERE
এটি এড়াতে এবং আরও দ্রুততর করার জন্য উপরের মতো প্রদর্শিত আরও একটি শর্ত যুক্ত করুন :
যদি status
সংজ্ঞায়িত করা হয় তবে আপনি এটিকে NOT NULL
সহজ করতে পারবেন:
AND status <> 'ACTIVE';
কলামের ডেটা ধরণের অবশ্যই <>
অপারেটরকে সমর্থন করবে । কিছু প্রকারের মতো json
নয়। দেখা:
NULL পরিচালনার ক্ষেত্রে সূক্ষ্ম পার্থক্য
এই ক্যোয়ারী ( বর্তমানে জোয়েলের গৃহীত উত্তরের মতো নয় ) নুল মানকে সমান হিসাবে বিবেচনা করে না। নিম্নলিখিত দুটি সারি (saleprice, saledate)
"স্বতন্ত্র" হিসাবে যোগ্যতা অর্জন করবে (যদিও মানুষের চোখের সাথে অভিন্ন দেখায়):
(123, NULL)
(123, NULL)
এছাড়াও একটি অনন্য সূচক এবং অন্য কোথাও পাস করে, যেহেতু NULL মানগুলি এসকিউএল স্ট্যান্ডার্ড অনুযায়ী সমান তুলনা করে না। দেখা:
OTOH, GROUP BY
, DISTINCT
বা DISTINCT ON ()
সমান হিসাবে আচরণ শূন্য মান। আপনি কী অর্জন করতে চান তার উপর নির্ভর করে একটি উপযুক্ত ক্যোয়ারী স্টাইল ব্যবহার করুন। আপনি এখনও এই দ্রুত কোয়েরিটিকে NUL তুলনা সমান করার জন্য কোনও বা সমস্ত তুলনার IS NOT DISTINCT FROM
পরিবর্তে এর সাথে ব্যবহার =
করতে পারেন। আরও:
যদি সমস্ত কলামের তুলনা করা হয় তা সংজ্ঞায়িত করা হয় NOT NULL
, তবে মতবিরোধের কোনও জায়গা নেই।