PostgreSQL का उपयोग करके एक ही क्वेरी में कई पंक्तियों को अपडेट करें


192

मैं एक बयान में PostgreSQL में कई पंक्तियों को अद्यतन करने के लिए देख रहा हूँ। क्या निम्नलिखित में से कुछ करने का एक तरीका है?

UPDATE table 
SET 
 column_a = 1 where column_b = '123',
 column_a = 2 where column_b = '345'

मैं इसे उस पृष्ठ पर खोजने का प्रयास करता रहता हूं, लेकिन मैं इसे प्राप्त नहीं कर सकता। मैं देखता हूं कि आप एक बयान के उपयोग से कहां से कई पंक्तियों को अपडेट कर सकते हैं, लेकिन मुझे यह नहीं मिलता कि प्रत्येक कथन के साथ कई पंक्तियों को कैसे अपडेट किया जाए। मैंने Google को भी खोजा और एक वास्तविक स्पष्ट उत्तर नहीं मिला, इसलिए मुझे उम्मीद थी कि कोई व्यक्ति इस पर एक स्पष्ट उदाहरण प्रदान कर सकता है।
newUserNameHere

माफ कीजिएगा यह मेरी गलती है। अपडेट किया गया।
शून्य 323

जवाबों:


427

आप update ... fromसिंटैक्स का भी उपयोग कर सकते हैं और एक मानचित्रण तालिका का उपयोग कर सकते हैं । यदि आप एक से अधिक कॉलम अपडेट करना चाहते हैं, तो यह बहुत अधिक सामान्य है:

update test as t set
    column_a = c.column_a
from (values
    ('123', 1),
    ('345', 2)  
) as c(column_b, column_a) 
where c.column_b = t.column_b;

आप जितने चाहें उतने कॉलम जोड़ सकते हैं:

update test as t set
    column_a = c.column_a,
    column_c = c.column_c
from (values
    ('123', 1, '---'),
    ('345', 2, '+++')  
) as c(column_b, column_a, column_c) 
where c.column_b = t.column_b;

sql fiddle demo


11
इसके अलावा, किसी को एक सही डेटा प्रकार निर्दिष्ट करना पड़ सकता है। एक तारीख के साथ एक उदाहरण: PostgreSQL प्रलेखन... from (values ('2014-07-21'::timestamp, 1), ('2014-07-20', 2), ... में अधिक विवरण
जोस एंडियास

महान काम करता है, स्पष्ट करने के लिए धन्यवाद! इसके लिए डाक्यूमेंट्स का दस्तावेजीकरण एक भ्रामक पढ़ने के लिए थोड़ा सा बनाता है।
स्कवेद्रेथ

52

@Roman के समाधान के आधार पर, आप कई मान सेट कर सकते हैं:

update users as u set -- postgres FTW
  email = u2.email,
  first_name = u2.first_name,
  last_name = u2.last_name
from (values
  (1, 'hollis@weimann.biz', 'Hollis', 'O\'Connell'),
  (2, 'robert@duncan.info', 'Robert', 'Duncan')
) as u2(id, email, first_name, last_name)
where u2.id = u.id;

4
यह उसके समाधान की तरह लगता है .. अद्यतन करें (मूल्य ...) जहां। यह केवल कैसे आधारित है?
इवान कैरोल

14
मैं इस उत्तर को पसंद करता हूं क्योंकि चर नाम समझने में आसान बनाते हैं कि क्या हो रहा है।
जॉन लेमन

वाह। स्पष्ट और स्पष्ट। मैं GoLang में कुछ इस तरह से लागू करने की कोशिश कर रहा हूं। तो क्या मैं मानों के लिए किसी संरचना का एक सरणी पास कर सकता हूं? कुछ इस तरह से, from (values $1)जहां $ 1 संरचना का एक सरणी है। उपरोक्त मामले में, सख्त के पास प्रॉपर्टी के रूप में आईडी, First_name और last_name होगा।
रेशमा सुरेश

26

हाँ तुम कर सकते हो:

UPDATE foobar SET column_a = CASE
   WHEN column_b = '123' THEN 1
   WHEN column_b = '345' THEN 2
END
WHERE column_b IN ('123','345')

और वर्किंग प्रूफ: http://sqlfiddle.com/# -2/ 97c7ea/1


8
यह गलत है ... आप सभी पंक्तियों को अपडेट करेंगे, भले ही वह '123'न हो '345'। आप का उपयोग करना चाहिए WHERE column_b IN ('123','456')...
MatheusOl

1
मुझे लगता है कि '456'माना जाता है'345'
रोमन पाकर

2
यदि आप ELSE column_bअंतिम WHEN ? THEN ?पंक्ति के बाद जोड़ते हैं , तो स्तंभ को वर्तमान मूल्य पर सेट किया जाएगा, इस प्रकार माथेउसक्यूआई ने कहा कि क्या होगा।
केविन ओरिस

1
यही वह नहीं है जो उसने मांगा था .. उसे कई बी अपडेट करने की जरूरत है, कॉल बी पर आधारित कॉल ए निर्धारित नहीं है
अमलगोविनस

क्या यह ठीक नहीं है जो ओपी ने पूछा है - केवल कॉलम_ए को अपडेट करने की आवश्यकता है (कॉलम_ बी के मूल्य के आधार पर), कई कॉलम नहीं, सही?
केवलर

3

इसी तरह के परिदृश्य में आया था और CASE अभिव्यक्ति मेरे लिए उपयोगी थी।

UPDATE reports SET is_default = 
case 
 when report_id = 123 then true
 when report_id != 123 then false
end
WHERE account_id = 321;

रिपोर्ट - यहां एक तालिका है, ऊपर उल्लिखित report_ids के लिए account_id समान है। उपरोक्त क्वेरी सत्य को 1 रिकॉर्ड (जो स्थिति से मेल खाती है) को सेट करेगी और सभी गैर-मिलान वाले झूठे होंगे।


2

एक क्वेरी में कई पंक्तियों को अपडेट करने के लिए , आप यह कोशिश कर सकते हैं

UPDATE table_name
SET 
column_1 = CASE WHEN any_column = value and any_column = value THEN column_1_value end,
column_2 = CASE WHEN any_column = value and any_column = value THEN column_2_value end,
column_3 = CASE WHEN any_column = value and any_column = value THEN column_3_value end,
.
.
.
column_n = CASE WHEN any_column = value and any_column = value THEN column_n_value end

यदि आपको अतिरिक्त शर्त की आवश्यकता नहीं है, तो andइस क्वेरी का हिस्सा हटा दें


0

मान लीजिए कि आपके पास आईडी और स्टेटस के बराबर सरणी की एक सरणी है - यहां एक उदाहरण है कि एरियर्स की स्थिर एसक्यूएल (एक sql क्वेरी जो विभिन्न मूल्यों के कारण नहीं बदलती) के साथ ऐसा कैसे करें:

drop table if exists results_dummy;
create table results_dummy (id int, status text, created_at timestamp default now(), updated_at timestamp default now());
-- populate table with dummy rows
insert into results_dummy
(id, status)
select unnest(array[1,2,3,4,5]::int[]) as id, unnest(array['a','b','c','d','e']::text[]) as status;

select * from results_dummy;

-- THE update of multiple rows with/by different values
update results_dummy as rd
set    status=new.status, updated_at=now()
from (select unnest(array[1,2,5]::int[]) as id,unnest(array['a`','b`','e`']::text[]) as status) as new
where rd.id=new.id;

select * from results_dummy;

-- in code using **IDs** as first bind variable and **statuses** as the second bind variable:
update results_dummy as rd
set    status=new.status, updated_at=now()
from (select unnest(:1::int[]) as id,unnest(:2::text[]) as status) as new
where rd.id=new.id;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.