PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

सम्मिलित तालिका से चयन करते हुए, एक ही क्वेरी में कई तालिकाओं में पंक्तियों को सम्मिलित करें

अंतिम संस्करण

... ओपी से कुछ और जानकारी के बाद। इस डेमो पर विचार करें:

-- 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

यह किसी अन्य की तरह सिर्फ एक चयन है - जिसमें वह तालिका शामिल हो सकती है जिसे आप सम्मिलित कर रहे हैं। पंक्तियों को पहले पढ़ा जाता है, और फिर डाला जाता है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL में पिवट टेबल कैसे बनाएं

  2. पोस्टग्रेज में सीरियल बढ़ाया जा रहा है, भले ही मैंने संघर्ष पर जोड़ा कुछ भी न करें

  3. पोस्टग्रेएसक्यूएल का बैकअप लेने के लिए बर्मन का उपयोग करना - एक सिंहावलोकन

  4. OmniDB के साथ PostgreSQL 12 के प्रदर्शन की निगरानी कैसे करें - भाग 2

  5. PostgreSQL:यदि मौजूद नहीं है तो तालिका बनाएं AS