अंतिम संस्करण
... ओपी से कुछ और जानकारी के बाद। इस डेमो पर विचार करें:
-- DROP TABLE foo; DROP TABLE bar;
CREATE TEMP TABLE bar (
id serial PRIMARY KEY -- using a serial column!
,z integer NOT NULL
);
CREATE TEMP TABLE foo (
id serial PRIMARY KEY -- using a serial column!
,x integer NOT NULL
,y integer NOT NULL
,bar_id integer UNIQUE NOT NULL REFERENCES bar(id)
);
मान डालें - bar
पहले।
यह बहुत सहायक होगा यदि आपने अपने प्रश्न में परीक्षण डेटा इस तरह प्रदान किया है!
INSERT INTO bar (id,z) VALUES
(100, 7)
,(101,16)
,(102,21);
INSERT INTO foo (id, x, y, bar_id) VALUES
(1, 3,4,100)
,(2, 9,6,101)
,(3,18,0,102);
अनुक्रमों को वर्तमान मानों पर सेट करें या हमें डुप्लीकेट कुंजी उल्लंघन मिलते हैं:
SELECT setval('foo_id_seq', 3);
SELECT setval('bar_id_seq', 102);
चेक:
-- SELECT nextval('foo_id_seq')
-- SELECT nextval('bar_id_seq')
-- SELECT * from bar;
-- SELECT * from foo;
प्रश्न:
WITH a AS (
SELECT f.x, f.y, bar_id, b.z
FROM foo f
JOIN bar b ON b.id = f.bar_id
WHERE x > 3
),b AS (
INSERT INTO bar (z)
SELECT z
FROM a
RETURNING z, id AS bar_id
)
INSERT INTO foo (x, y, bar_id)
SELECT a.x, a.y, b.bar_id
FROM a
JOIN b USING (z);
यह वही करना चाहिए जो आपका अंतिम अपडेट वर्णन करता है।
क्वेरी मानती है कि z
है UNIQUE
. अगर z
अद्वितीय नहीं है, यह अधिक जटिल हो जाता है। विंडो फ़ंक्शन row_number()
. का उपयोग करके तैयार समाधान के लिए इस संबंधित उत्तर में प्रश्न 2 देखें इस मामले में।
साथ ही, 1:1 संबंध . को बदलने पर विचार करें foo
. के बीच और bar
एक संयुक्त तालिका के साथ।
डेटा संशोधित सीटीई
अधिक जानकारी के बाद दूसरा उत्तर।
अगर आप foo
. में पंक्तियां जोड़ना चाहते हैं और bar
एक ही क्वेरी में, आप PostgreSQL 9.1 . के बाद से CTE को संशोधित करने वाले डेटा का उपयोग कर सकते हैं :
WITH x AS (
INSERT INTO bar (col1, col2)
SELECT f.col1, f.col2
FROM foo f
WHERE f.id BETWEEN 12 AND 23 -- some filter
RETURNING col1, col2, bar_id -- assuming bar_id is a serial column
)
INSERT INTO foo (col1, col2, bar_id)
SELECT col1, col2, bar_id
FROM x;
मैं foo
. से मान लेता हूं , उन्हें bar
. में डालें , क्या उन्हें एक ऑटो-जेनरेटेड bar_id
. के साथ एक साथ लौटा दिया गया है और डालें कि foo
. में . आप किसी अन्य डेटा का भी उपयोग कर सकते हैं।
यहाँ sqlfiddle पर खेलने के लिए एक कार्यशील डेमो है।
मूल बातें
स्पष्टीकरण से पहले मूल जानकारी के साथ मूल उत्तर।
मूल रूप है:
INSERT INTO foo (...)
SELECT ... FROM foo WHERE ...
कोष्ठक की आवश्यकता नहीं है। आप इसे किसी भी तालिका के साथ कर सकते हैं
INSERT INTO foo (...)
SELECT ... FROM bar WHERE ...
और आप उस तालिका में शामिल हो सकते हैं जिसे आप SELECT में सम्मिलित करते हैं:
INSERT INTO foo (...)
SELECT f.col1, f.col2, .. , b.bar_id
FROM foo f
JOIN bar b USING (foo_id); -- present in foo and bar
यह किसी अन्य की तरह सिर्फ एक चयन है - जिसमें वह तालिका शामिल हो सकती है जिसे आप सम्मिलित कर रहे हैं। पंक्तियों को पहले पढ़ा जाता है, और फिर डाला जाता है।