অন্য একের ক্ষেত্র থেকে এক টেবিলের এসকিউএল আপডেট ক্ষেত্র


124

আমার দুটি টেবিল রয়েছে:

A [ID, column1, column2, column3]
B [ID, column1, column2, column3, column4]

Aসর্বদা সাবসেট থাকবে B(অর্থাত্ সমস্ত কলামগুলিও এর Aমধ্যে রয়েছে B)।

আমি একটি নির্দিষ্ট সঙ্গে একটি রেকর্ড আপডেট করতে চান IDমধ্যে Bথেকে তাদের তথ্য দিয়ে Aসব কলামের জন্য A। এই IDউভয় বিদ্যমান Aএবং B

সেখানে একটা হয় UPDATEসিনট্যাক্স বা যে কাজ করতে কলাম নামে উল্লেখ না করে অন্য কোন উপায়, শুধু বলার অপেক্ষা রাখে না "একজন এর সব কলাম সেট করুন" ?

আমি পোস্টগ্রিজ এসকিউএল ব্যবহার করছি, সুতরাং একটি নির্দিষ্ট অ-মানক কমান্ডও গৃহীত হবে (তবে, পছন্দসই নয়)।


আমি মনে করি এটিই আপনি করতে চান, dba.stackexchange.com/a/58383
zubair-0

উত্তর:


234

আপনি অ-মানক FROM ধারাটি ব্যবহার করতে পারেন ।

UPDATE b
SET column1 = a.column1,
  column2 = a.column2,
  column3 = a.column3
FROM a
WHERE a.id = b.id
AND b.id = 1

9
প্রশ্ন হল কিভাবে এটা করতে সম্পর্কে জিজ্ঞাসা করা হয় ছাড়া সব কলাম নামে উল্লেখ। (এবং আমিও আছি))
ক্লুস্কু

2
আমি @ ক্ল্যাসোকের সাথে একমত, তবে এই উত্তরটি অন্য সারণীতে একটি কলামে মানগুলি প্রতিস্থাপনের জন্য সন্ধানের সারণী হিসাবে একটি কলামের এক কলামে মানগুলি ব্যবহার করার একটি দুর্দান্ত উপায় ( সুতরাং 21657475 দেখুন ), সুতরাং +1 ...
ভিক্টোরিয়া স্টুয়ার্ট

1
বি.আইডি = 1 কেন দরকার?
ইয়াসিরআজগার

1
@ ইয়াসিরআজগার বি.আইডি = 1 হ'ল বিতে থাকা সারিগুলি সীমাবদ্ধ করা। অন্যথায় আমরা টেবিলের প্রতিটি সারি আপডেট করব। মাঝে মাঝে, আপনি যা চান তা হতে পারে। তবে মূল প্রশ্নটি ছিল একটি নির্দিষ্ট সারিতে খ।
স্কট বেইলি

আমার বিশেষ সমস্যার জন্য আমার এটির দরকার ছিল: অন্য সারণীর ভিন্ন-নামকরণযুক্ত কলাম থেকে মান সহ একটি টেবিলের কলাম আপডেট করা।
muad-dweeb

49

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

কলামের নাম উল্লেখ না করে একটি UPDATEবাক্য গঠন আছে ... ?

ডায়নামিক এসকিউএল সহ সাধারণ সমাধান

( idউদাহরণস্বরূপ) যোগদানের জন্য কিছু অনন্য কলাম (গুলি) ব্যতীত আপনার কোনও কলামের নাম জানতে হবে না । আমি ভাবতে পারি যে কোনও সম্ভাব্য কোণার ক্ষেত্রে নির্ভরযোগ্যভাবে কাজ করে।

এটি পোস্টগ্রাইএসকিউএল-এর জন্য নির্দিষ্ট। আমি গতিশীল উপর ভিত্তি করে কোড বিল্ডিং করছি information_schema বিশেষ টেবিলে, information_schema.columnsযা এসকিউএল মান এবং সবচেয়ে প্রধান RDBMS (ওরাকল ব্যতীত) সংজ্ঞায়িত করা হয় এটা আছে। তবে ডায়ামিক এসকিউএল সম্পাদনকারী পিএল / পিজিএসকিউএল কোড DOসহ একটি বিবৃতি সম্পূর্ণ অ-মানক পোস্টগ্রিসএসকিউএল সিনট্যাক্স।

DO
$do$
BEGIN

EXECUTE (
SELECT
  'UPDATE b
   SET   (' || string_agg(        quote_ident(column_name), ',') || ')
       = (' || string_agg('a.' || quote_ident(column_name), ',') || ')
   FROM   a
   WHERE  b.id = 123
   AND    a.id = b.id'
FROM   information_schema.columns
WHERE  table_name   = 'a'       -- table name, case sensitive
AND    table_schema = 'public'  -- schema name, case sensitive
AND    column_name <> 'id'      -- all columns except id
);

END
$do$;

একটি ম্যাচিং কলাম ধরে নেওয়া যাক bজন্য যে কলাম a, কিন্তু না অন্য উপায় বৃত্তাকার। bঅতিরিক্ত কলাম থাকতে পারে।

WHERE b.id = 123 selectedচ্ছিক, একটি নির্বাচিত সারি আপডেট করতে।

এসকিউএল ফিডল।

আরও ব্যাখ্যা সহ সম্পর্কিত উত্তর:

প্লেইন এসকিউএল সহ আংশিক সমাধান

ভাগ করা কলামগুলির তালিকা সহ

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

UPDATE b
SET   (  column1,   column2,   column3)
    = (a.column1, a.column2, a.column3)
FROM   a
WHERE  b.id = 123    -- optional, to update only selected row
AND    a.id = b.id;

এসকিউএল ফিডল।

এই সিনট্যাক্সটি প্রশ্ন জিজ্ঞাসার অনেক আগে 2006 সালে পোস্টগ্রিস 8.2 এর সাথে প্রবর্তিত হয়েছিল। ম্যানুয়ালটিতে বিশদ।

সম্পর্কিত:

কলামের তালিকা সহ B

যদি সমস্ত কলামগুলি Aসংজ্ঞায়িত করা হয় NOT NULL(তবে প্রয়োজনীয় নয় B),
এবং আপনি কলামের নামগুলি জানেনB (তবে প্রয়োজনীয়ভাবে নয় A)।

UPDATE b
SET   (column1, column2, column3, column4)
    = (COALESCE(ab.column1, b.column1)
     , COALESCE(ab.column2, b.column2)
     , COALESCE(ab.column3, b.column3)
     , COALESCE(ab.column4, b.column4)
      )
FROM (
   SELECT *
   FROM   a
   NATURAL LEFT JOIN  b -- append missing columns
   WHERE  b.id IS NULL  -- only if anything actually changes
   AND    a.id = 123    -- optional, to update only selected row
   ) ab
WHERE b.id = ab.id;

NATURAL LEFT JOINথেকে একটি সারিতে যোগদান করে bযেখানে একই নামের সব কলাম একই মান ধরে রাখুন। আমাদের এক্ষেত্রে আপডেটের দরকার নেই (কোনও পরিবর্তন হয় না) এবং প্রক্রিয়া শুরুর দিকে ( WHERE b.id IS NULL)) সারিগুলি সরাতে পারি ।
আমাদের এখনও একটি মিলের সারিটি খুঁজে পাওয়া দরকার, সুতরাং b.id = ab.idবাহ্যিক ক্যোয়ারিতে।

ডিবি <> ফ্রিডল এখানে
পুরাতন স্ক্যালফিল্ড।

এটি ক্লজ বাদেFROM স্ট্যান্ডার্ড এসকিউএল ।
কোন কলামটি প্রকৃতপক্ষে উপস্থিত Aতা বিবেচনা করেই কার্যকর হয় , তবে কোয়েরিটি প্রকৃত NULL মান এবং অনুপস্থিত কলামগুলির মধ্যে পার্থক্য করতে পারে না A, সুতরাং সমস্ত কলাম Aসংজ্ঞায়িত করা হলে এটি কেবল নির্ভরযোগ্য NOT NULL

উভয় সারণী সম্পর্কে আপনি কী জানেন তার উপর নির্ভর করে একাধিক সম্ভাব্য প্রকরণ রয়েছে ।


এসকিউএল এর শক্তি! আপনি যখন সেট ক্লজে ( SET (column1) = (a.column)) পোস্টগ্রেসেস যুক্ত করবেন তখন ঠিক লক্ষ্য করেছেন পোস্টগ্র্রেস এটিকে অন্য ধরণের আপডেট হিসাবে বিবেচনা করবে এবং এর মতো ভুল এবং ত্রুটি দেবে:source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression
এডগার অরটেগা

26

আমি আরও দশক ধরে আইবিএম ডিবি 2 ডাটাবেসের সাথে কাজ করছি এবং এখন পোস্টগ্র্যাসকিউএল শিখার চেষ্টা করছি।

এটি PostgreSQL 9.3.4 এ কাজ করে তবে DB2 10.5 এ কাজ করে না:

UPDATE B SET
     COLUMN1 = A.COLUMN1,
     COLUMN2 = A.COLUMN2,
     COLUMN3 = A.COLUMN3
FROM A
WHERE A.ID = B.ID

দ্রষ্টব্য: প্রধান সমস্যা হ'ল FROM কারণ যা ডিবি 2 তে সমর্থিত নয় এবং এএনএসআই এসকিউএলেও নয়।

এটি DB2 10.5 এ কাজ করে তবে পোস্টগ্রিসকিউএল 9.3.4 এ কাজ করে না:

UPDATE B SET
    (COLUMN1, COLUMN2, COLUMN3) =
               (SELECT COLUMN1, COLUMN2, COLUMN3 FROM A WHERE ID = B.ID)

অবশেষে! এটি পোস্টগ্র্যাস এসকিউএল 9.3.4 এবং ডিবি 2 10.5 উভয় ক্ষেত্রেই কাজ করে:

UPDATE B SET
     COLUMN1 = (SELECT COLUMN1 FROM A WHERE ID = B.ID),
     COLUMN2 = (SELECT COLUMN2 FROM A WHERE ID = B.ID),
     COLUMN3 = (SELECT COLUMN3 FROM A WHERE ID = B.ID)

3
নোট করুন যে দ্বিতীয় এবং তৃতীয় ক্যোয়ারীগুলি প্রথমটির সাথে সম্পূর্ণ সমতুল্য নয়। যদি কোনও মিলের সারিটি পাওয়া যায় না B, তবে প্রথম বিবৃতিটি কিছুই করে না (মূল সারিটি ছোঁয়া থাকে), অন্য দুটি নূন্যমূল্য সহ কলামগুলিকে ওভাররাইট করে।
এরউইন ব্র্যান্ডসটেটার

7

এটি একটি দুর্দান্ত সাহায্য। কোড

UPDATE tbl_b b
SET   (  column1,   column2,   column3)
    = (a.column1, a.column2, a.column3)
FROM   tbl_a a
WHERE  b.id = 1
AND    a.id = b.id;

পুরোপুরি কাজ করে।

আপনার ব্র্যাককেট "" দরকার বলে উল্লেখ করেছেন

From "tbl_a" a

এটা কাজ করতে.


5

অগত্যা আপনি যা জিজ্ঞাসা করেছিলেন তা নয়, তবে পোস্টগ্রিসের উত্তরাধিকার ব্যবহার সাহায্য করতে পারে?

CREATE TABLE A (
    ID            int,
    column1       text,
    column2       text,
    column3       text
);

CREATE TABLE B (
    column4       text
) INHERITS (A);

এটি বি আপডেট করার প্রয়োজনীয়তা এড়ায়

তবে অবশ্যই সমস্ত বিবরণ পড়তে ভুলবেন না

অন্যথায়, আপনি যা চেয়েছেন তা একটি ভাল অনুশীলন হিসাবে বিবেচিত হবে না - গতিশীল স্টাফ যেমন মতামতগুলি SELECT * ...নিরুৎসাহিত করা হয় (যেমন সামান্য সুবিধা সাহায্যের চেয়ে আরও বেশি জিনিস ভেঙে দিতে পারে), এবং আপনি যা চেয়েছিলেন তা UPDATE ... SETআদেশের সমতুল্য হবে ।


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

2
হ্যাঁ, যদি এটি কেবলমাত্র কিছু ক্ষেত্রে হয় তবে উত্তরাধিকার কাজ করবে না এবং সেই ক্ষেত্রে আমি গতিশীল ক্যোয়ারী পদ্ধতির বিরুদ্ধে পরামর্শ দিই। (এখনও পোস্টগ্রিস প্রক্রিয়াজাতীয় ভাষা ব্যবহার করে এটি অর্জনের উপায় রয়েছে you আপনি যদি ট্রিগার ব্যবহার করতে চান তবে আপনি সেগুলিও ব্যবহার করতে পারেন - উদাহরণস্বরূপ সিঙ্ক ক্ষেত্র যুক্ত করে ফায়ারিং ট্রিগার কেবল সেট করা থাকলে)।
অবাস্তব

0

এটি করার জন্য আপনি গতিশীল এসকিএল তৈরি এবং চালিত করতে পারেন, তবে এটি সত্যই আদর্শ নয়


আমি সে সম্পর্কে ভেবেছিলাম। আমি ভেবেছিলাম যে আমি উভয় টেবিলের পরবর্তী পরিবর্তনের সাথে আমার ক্যোয়ারীটির সাথে সামঞ্জস্য করতে পারি তবে গতিশীল এসকিউএল কেবলমাত্র সমস্ত ক্ষেত্র নির্দিষ্ট করে এবং সামনের দিকে সামঞ্জস্যতা ভুলে যাওয়ার চেয়ে জটিল বলে মনে হচ্ছে।
নীড়

হ্যাঁ, এটি জটিল হবে, তবে পরবর্তী কলামগুলি যোগ করা বা অপসারণের সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত। উভয় টেবিল থেকে কলামের নাম পেতে আপনাকে প্রথমে একটি কোয়েরি করতে হবে, তারপরে কলামের নামগুলি মেলাতে হবে এবং তারপরে ম্যাচের কলামের নামের সাথে মিল রেখে আপডেটটি করতে ডায়নামিক এসকিএল লিখতে হবে। আসলে একটি মজাদার প্রকল্প :)
ড্যানিয়েল ব্রিংক

-4

অনুসরণ করার চেষ্টা করুন

Update A a, B b, SET a.column1=b.column1 where b.id=1

সম্পাদিত: - একাধিক কলাম আপডেট করুন

Update A a, B b, SET a.column1=b.column1, a.column2=b.column2 where b.id=1

এটি কীভাবে কলাম 1, কলাম 2 এবং কলাম 3 অনুলিপি করে তা আমি বুঝতে পারি না। এবং আমার স্পষ্টভাবে কলাম 1 উল্লেখ করার দরকার নেই।
নীড়

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

1
এই অ-মানক সিনট্যাক্সটি UPDATEমাইএসকিউএল-তে কাজ করবে তবে পোস্টগ্র্রেএসকিউএল-এর জন্য এটি অবৈধ।
এরউইন ব্র্যান্ডসটেটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.