सवाल पुराना है, लेकिन मुझे लगा कि सबसे अच्छा जवाब नहीं दिया गया है, फिर भी।
क्या कॉलम नामों को निर्दिष्ट किए बिना एक UPDATE
वाक्यविन्यास है ... ?
डायनेमिक SQL के साथ सामान्य समाधान
इसमें शामिल होने के लिए आपको कुछ अद्वितीय स्तंभों को छोड़कर किसी भी स्तंभ के नाम को जानने की आवश्यकता नहीं है (id
उदाहरण में) । किसी भी संभावित कोने के मामले में मज़बूती से काम कर सकता हूँ।
यह PostgreSQL के लिए विशिष्ट है। मैं information_schema के आधार पर डायनामिक कोड बना रहा हूं , विशेष रूप से तालिका में information_schema.columns
, जो कि SQL मानक में परिभाषित है और अधिकांश प्रमुख RDBMS (Oracle को छोड़कर) है। लेकिन पीएल / pgSQL कोड के DO
साथ एक बयान गतिशील एसक्यूएल निष्पादित पूरी तरह से गैर-मानक PostgreSQL सिंटैक्स है।
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
वैकल्पिक है, चयनित पंक्ति को अद्यतन करने के लिए।
एसक्यूएल फिडल।
अधिक स्पष्टीकरण के साथ संबंधित जवाब:
सादे एसक्यूएल के साथ आंशिक समाधान
साझा कॉलम की सूची के साथ
आपको अभी भी उन स्तंभ नामों की सूची जानने की आवश्यकता है जो दोनों तालिकाएं साझा करती हैं। कई कॉलमों को अपडेट करने के लिए एक सिंटैक्स शॉर्टकट के साथ - किसी भी मामले में अब तक सुझाए गए अन्य उत्तरों से कम।
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
बाहरी क्वेरी में।
db <> फिडेल यहाँ
पुराना फिडेल sqlfiddle।
यह क्लॉज को छोड़करFROM
मानक SQL है ।
इससे कोई फर्क नहीं पड़ता कि कौन से स्तंभ वास्तव में मौजूद हैं A
, लेकिन क्वेरी वास्तविक NULL मानों और अनुपलब्ध स्तंभों के बीच अंतर नहीं कर सकती है A
, इसलिए यह केवल विश्वसनीय है यदि सभी स्तंभों A
को परिभाषित किया गया हैNOT NULL
।
दोनों तालिकाओं के बारे में आप जो जानते हैं उसके आधार पर कई संभावित भिन्नताएं हैं ।