পোস্টগ্রিএসকিউএল-এ কীভাবে একটি আপডেট + যোগ করবেন?


506

মূলত, আমি এটি করতে চাই:

update vehicles_vehicle v 
    join shipments_shipment s on v.shipment_id=s.id 
set v.price=s.price_per_vehicle;

আমি নিশ্চিত যে এটি মাইএসকিউএল (আমার পটভূমি) এ কাজ করবে তবে এটি পোস্টগ্রাগে কাজ করবে বলে মনে হয় না। আমি যে ত্রুটি পেয়েছি তা হ'ল:

ERROR:  syntax error at or near "join"
LINE 1: update vehicles_vehicle v join shipments_shipment s on v.shi...
                                  ^

অবশ্যই এটি করার একটি সহজ উপায় আছে তবে আমি সঠিক বাক্য গঠন খুঁজে পাই না। সুতরাং, আমি পোস্টগ্র্রেএসকিউএল এ কিভাবে লিখব?


5
পোস্টগ্রিস সিনট্যাক্স পৃথক: postgresql.org/docs/8.1/static/sql-update.html
মার্ক বি

4
যানবাহন_বাহন, চালান_শপমেন্ট? এটি একটি আকর্ষণীয় টেবিলের নামকরণের কনভেনশন
কোডঅ্যান্ডক্যাটস

3
@ কোডএন্ডক্যাটস হাহাহা ... এটা মজার দেখাচ্ছে না তাই না? আমি মনে করি আমি তখন জ্যাঙ্গো ব্যবহার করছিলাম এবং টেবিলগুলি বৈশিষ্ট্য অনুসারে গোষ্ঠীভুক্ত হয়েছে। সুতরাং সেখানে একটি ভিউ vehicles_*টেবিল এবং কয়েকটি shipments_*টেবিল থাকত ।
এমপেন

উত্তর:


775

আপডেট সিনট্যাক্স হল:

[জিজ্ঞাসাবাদ [[...]] সহ [পুনরাবৃত্ত]
[কেবলমাত্র] টেবিল আপডেট করুন [[AS] ওরফে]
    SET {কলাম = {প্রকাশ | ডিফল্ট} |
          (কলাম [, ...]) = ({প্রকাশ | ডিফল্ট} [, ...])} [, ...]
    [থেকে তালিকাভুক্ত]
    [যেখানে অবস্থা | কার্সার_নামের সীমাবদ্ধতা]
    [প্রত্যাবর্তন * | আউটপুট_প্রকাশ [[AS] আউটপুট_নাম] [, ...]]

আপনার ক্ষেত্রে আমি মনে করি আপনি এটি চান:

UPDATE vehicles_vehicle AS v 
SET price = s.price_per_vehicle
FROM shipments_shipment AS s
WHERE v.shipment_id = s.id 

আপডেটটি যদি টেবিলের সাথে যোগ হয় এমন একটি সম্পূর্ণ তালিকার উপর নির্ভর করে তবে সেগুলি কি আপডেটের বিভাগে বা FROM বিভাগে থাকা উচিত?
ted.strauss

11
@ ted.strauss: FROM এ টেবিলের একটি তালিকা থাকতে পারে।
মার্ক বায়ার্স

140

আমার উদাহরণ দিয়ে আমাকে আরও কিছুটা ব্যাখ্যা করুন।

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

এভাবে। পরবর্তী মাইএসকিউএল-মত বিবৃতি:

UPDATE applications a
JOIN (
    SELECT ap.id, ab.certificate_issued_at
    FROM abiturients ab
    JOIN applications ap 
    ON ab.id = ap.abiturient_id 
    WHERE ap.documents_taken_at::date < ab.certificate_issued_at
) b
ON a.id = b.id
SET a.documents_taken_at = b.certificate_issued_at;

পোস্টগ্র্রেএসকিউএল-এর মতো হয়ে যায়

UPDATE applications a
SET documents_taken_at = b.certificate_issued_at         -- we can reference joined table here
FROM abiturients b                                       -- joined table
WHERE 
    a.abiturient_id = b.id AND                           -- JOIN ON clause
    a.documents_taken_at::date < b.certificate_issued_at -- Subquery WHERE

যেহেতু আপনি দেখতে পারেন, মূল subquery JOINএর ONদফা এক হয়ে গেছে WHEREশর্ত, যার দ্বারা conjucted হয় ANDঅন্যদের, যা subquery কাছ থেকে কোন পরিবর্তনের সঙ্গে সরানো হয়েছে সঙ্গে। এবং JOINনিজের সাথে টেবিল দেওয়ার আর কোনও প্রয়োজন নেই (যেমন এটি উপকৃত ছিল)।


16
তৃতীয় টেবিলে আপনি কীভাবে যোগদান করবেন?
গ্রোলার

19
আপনি কেবলমাত্র তালিকায় JOINযথারীতি FROM:FROM abiturients b JOIN addresses c ON c.abiturient_id = b.id
এনভেক

@ এনভেক - হায় আপনি সেখানে যোগদান করতে পারবেন না, আমি ঠিক পরীক্ষা করেছিলাম। postgresql.org/docs/10/static/sql-update.html
অ্যাড্রিয়ান স্মিথ

3
@ অ্যাড্রিয়ানস্মিথ, আপনি নিজেই আপডেট আপ যোগদান করতে পারবেন না, তবে এটি আপডেটের ধারাটিতে ব্যবহার করতে পারেন from_list(যা পোস্টগ্র্রেএসকিউএল এর এসকিউএল এক্সটেনশন)। এছাড়াও, আপনার সরবরাহিত লিঙ্কটিতে টেবিলের সাবধানে যোগ দেওয়ার বিষয়ে নোটগুলি দেখুন।
এনভেক

@ এনভেক - আহ, স্পষ্টির জন্য আপনাকে ধন্যবাদ, আমি এটি মিস করেছি।
অ্যাড্রিয়ান স্মিথ

130

মার্ক বাইয়ার্স এর উত্তর এই পরিস্থিতিতে অনুকূল। যদিও আরও জটিল পরিস্থিতিতে আপনি নির্বাচিত ক্যোয়ারী নিতে পারেন যা সারিগুলি এবং গণনা করা মানগুলি ফিরিয়ে দেয় এবং আপডেট আপডেটের ক্যোয়ারিতে এটির মতো সংযুক্ত করে:

with t as (
  -- Any generic query which returns rowid and corresponding calculated values
  select t1.id as rowid, f(t2, t2) as calculatedvalue
  from table1 as t1
  join table2 as t2 on t2.referenceid = t1.id
)
update table1
set value = t.calculatedvalue
from t
where id = t.rowid

এই পদ্ধতির সাহায্যে আপনি আপনার নির্বাচিত ক্যোয়ারীটি বিকাশ এবং পরীক্ষা করতে পারবেন এবং দুটি পদক্ষেপে এটিকে আপডেট ক্যোয়ারিতে রূপান্তর করুন।

সুতরাং আপনার ক্ষেত্রে ফলাফল কোয়েরি হবে:

with t as (
    select v.id as rowid, s.price_per_vehicle as calculatedvalue
    from vehicles_vehicle v 
    join shipments_shipment s on v.shipment_id = s.id 
)
update vehicles_vehicle
set price = t.calculatedvalue
from t
where id = t.rowid

নোট করুন যে কলামের নাম অবশ্যই বাধ্যতামূলক are


1
আমি সত্যিই এটি পছন্দ করি কারণ আমি সর্বদা আমার "সিলেক্ট" উপরের দিকে নিয়ে যায় এবং এটিকে একটি "আপডেট" দিয়ে প্রতিস্থাপন করে বিশেষত একাধিক যোগদানের সাথে ঘাবড়ে যাই। এটি বৃহত্তর আপডেটের আগে আমার করা এসকিউএল ডাম্পের সংখ্যা হ্রাস করে। :)
ড্যানিসাউয়ার

5
নিশ্চিত না কেন, তবে এই ক্যোয়ারির সিটিই সংস্করণটি উপরের "প্লেইন জয়েন" সমাধানগুলির চেয়ে বেশ দ্রুত গতিতে রয়েছে
পল.এগ্রো

এই সমাধানটির অন্য সুবিধাটি হ'ল / সিলেক্ট স্টেটমেন্টের সাথে একাধিক যোগদান করে আপনার চূড়ান্ত গণনা করা মানটি পেতে দুটিরও বেশি টেবিল থেকে যোগদানের ক্ষমতা।
অ্যালেক্স মুরো

1
এটা সত্যিই দারুন. আমি আমার নির্বাচিত কারুকাজ করেছি এবং @ উদ্যানসৌয়ের মত, আমি রূপান্তরটি দেখে ভয় পেয়েছিলাম। এটি কেবল আমার জন্য এটি করে। পারফেক্ট!
হিমশীতল

1
আপনার প্রথম এসকিউএল উদাহরণটিতে একটি সিনট্যাক্স ত্রুটি রয়েছে। "আপডেট টি 1" টি টি উপকোয়ারির থেকে উপনামটি ব্যবহার করতে পারে না, এটির সারণির নামটি ব্যবহার করা দরকার: "টেবিল 1 আপডেট করুন"। আপনি এটি আপনার দ্বিতীয় উদাহরণে সঠিকভাবে করেন।
এরিকস

79

আসলে যা করতে চান তাদের জন্য JOINআপনি এটিও ব্যবহার করতে পারেন:

UPDATE a
SET price = b_alias.unit_price
FROM      a AS a_alias
LEFT JOIN b AS b_alias ON a_alias.b_fk = b_alias.id
WHERE a_alias.unit_name LIKE 'some_value' 
AND a.id = a_alias.id;

SETপ্রয়োজনে সমান চিহ্নের ডানদিকে বিভাগে a_alias ব্যবহার করতে পারেন । সমান চিহ্নের বামে ক্ষেত্রগুলিকে কোনও টেবিলের রেফারেন্সের প্রয়োজন হয় না কারণ এগুলিকে মূল "একটি" সারণী থেকে মনে করা হয়।


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

এটা কাজ করে। তবে হ্যাকের মতো মনে হচ্ছে
এম হাবিব

এটি নোট করা উচিত যে ডকুমেন্টেশন অনুসারে ( postgresql.org/docs/11/sql-update.html ), ধারা থেকে লক্ষ্য সারণি তালিকাভুক্তকরণ লক্ষ্য টেবিলটি স্ব-যোগদানের কারণ হতে পারে। কম আত্মবিশ্বাসের সাথে, আমার কাছে এটিও উপস্থিত হয় যে এটি একটি ক্রস-স্ব-যোগদান, যার অনিচ্ছাকৃত ফলাফল এবং / অথবা পারফরম্যান্সের প্রভাব থাকতে পারে।
বেন কলিন্স

12

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

UPDATE a
SET price = b_alias.unit_price
FROM      a AS a_alias
LEFT JOIN b AS b_alias ON a_alias.b_fk = b_alias.id
WHERE a_alias.unit_name LIKE 'some_value' 
AND a.id = a_alias.id
--the below line is critical for updating ONLY joined rows
AND a.pk_id = a_alias.pk_id;

এটি উপরে উল্লিখিত হয়েছিল তবে কেবলমাত্র একটি মন্তব্যের মাধ্যমে..তখন সঠিক ফলাফল পোস্ট করা জরুরী যে নতুন উত্তরটি কাজ করে


7

এখানে আমরা যাচ্ছি:

update vehicles_vehicle v
set price=s.price_per_vehicle
from shipments_shipment s
where v.shipment_id=s.id;

আমি এটি করতে পারে হিসাবে সহজ। ধন্যবাদ বন্ধুরা!

এটিও করতে পারেন:

-- Doesn't work apparently
update vehicles_vehicle 
set price=s.price_per_vehicle
from vehicles_vehicle v
join shipments_shipment s on v.shipment_id=s.id;

তবে তারপরে আপনি সেখানে দু'বার গাড়ির টেবিল পেয়েছেন এবং আপনাকে কেবল একবার এটির নাম দেওয়ার অনুমতি দেওয়া হয়েছে এবং আপনি "সেট" অংশে উপনামটি ব্যবহার করতে পারবেন না।


আপনি কি এই সম্পর্কে নিশ্চিত? না joinএটা সীমাবদ্ধ?
এমপিএন

4
@ পেনপেন আমি নিশ্চিত করতে পারি যে এটি সমস্ত রেকর্ডকে একটি মানতে আপডেট করে। এটি আপনি যা আশা করবেন তা করে না।
অ্যাডাম বেল

1

এখানে একটি সরল এসকিউএল রয়েছে যা নাম থেকে মধ্য_নাম ক্ষেত্রটি ব্যবহার করে নাম 3 টেবিলে মিড_নাম আপডেট করে:

update name3
set mid_name = name.middle_name
from name
where name3.person_id = name.person_id;

0

নীচের লিঙ্কে একটি উদাহরণ সমাধানে হয়েছে এবং ভাল কিভাবে ব্যবহার understant সাহায্য করে updateএবং joinpostgres সঙ্গে।

UPDATE product
SET net_price = price - price * discount
FROM
product_segment
WHERE
product.segment_id = product_segment.id;

দেখুন: http://www.postgresqltutorial.com/postgresql-update-join/


0

প্রথম সারণীর নাম: tbl_table1 (ট্যাব 1)। দ্বিতীয় সারণীর নাম: tbl_table2 (ট্যাব 2)।

Tbl_table1 এর ac_status কলামটি "সংক্রামক" এ সেট করুন

update common.tbl_table1 as tab1
set ac_status= 'INACTIVE' --tbl_table1's "ac_status"
from common.tbl_table2 as tab2
where tab1.ref_id= '1111111' 
and tab2.rel_type= 'CUSTOMER';
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.