2013-04-20 10 views
6

मैं एक एकल पोस्टग्रेस एसक्यूएल कथन लिखना चाहता हूं जो कहता है कि रंग एक्स और चमक वाई के साथ उपयोगकर्ता की तलाश है। यदि वह उपयोगकर्ता मौजूद है, तो इसके सभी पंक्ति डेटा लौटाएं। यदि नहीं, तो एक नई पंक्ति बनाएं और अतिरिक्त जानकारी पास करें। दो अलग-अलग बयान कुछ इस तरह करना होगा:पोस्टग्रेस लिखें या SQL क्वेरी

Select (color, brightness, size, age) FROM mytable WHERE color = 'X' AND brightness= 'Y'; 

कि कुछ भी वापस नहीं करता है, तो इस पर अमल:

INSERT INTO mytable (color, brightness, size, age) VALUES (X, Y, big, old); 

वहाँ किसी एक क्वेरी में इन गठबंधन करने के लिए एक रास्ता है ??

+0

'INSERT' कथन पर पोस्टग्रेस्क्ल के 'रिटर्निंग' क्लॉज एक्सटेंशन को देखते हुए, मैंने शुरू में उम्मीद की थी कि कोई यूनियन का उपयोग करके एक कथन में एक चयन के साथ एक सम्मिलन को जोड़ सकता है, लेकिन मैंने कोशिश की और दुर्भाग्य से पढ़ता है और लिखना वास्तव में असंभव है उस तरफ। – didierc

उत्तर

15

किसी SQL डीबीएमएस में, चुनें परीक्षण-डालने दृष्टिकोण गलती है: कुछ भी नहीं आपके select और insert बयानों के बीच "लापता" पंक्ति सम्मिलित करने से किसी अन्य प्रक्रिया को रोकता है। इसके बजाय इसे करें:

insert into mytable (color, brightness, size, age) 
select (color, brightness, size, age) from mytable 
where not exists (
    select 1 from 
    from mytable 
    where color = 'X' and brightness = 'Y' 
); 
SELECT (color, brightness, size, age) 
FROM mytable 
WHERE color = 'X' AND brightness= 'Y'; 

आपको उस पूरे पाठ को डीबीएमएस को एक "क्वेरी" के रूप में पारित करने में सक्षम होना चाहिए। आप इसे संग्रहीत प्रक्रिया में बनाने पर विचार करना चाहेंगे।

+0

इस उत्तर से संबंधित, और बेहतर समझने के लिए उपयोगी: http://stackoverflow.com/a/13342031/399726 – BenjaminGolder

+0

यह समझ में नहीं आता कि इस उत्तर ने सिंटैक्स त्रुटि वाले कितने वोट एकत्र किए हैं। Postgres में INSERT के लिए कोई विकल्प 'डालने ... कहां ...' नहीं है। आप शायद 'मायटेबल (रंग, चमक, आकार, आयु) में' एक्स ',' वाई ', 1.2, 3.4 चुनें जहां मौजूद नहीं है ... '। – greatvovan

4
with sel as (
    select color, brightness, size, age 
    from mytable 
    where color = 'X' and brightness = 'Y' 
), ins as (
    insert into mytable (color, brightness, size, age) 
    select 'X', 'Y', 6.2, 40 
    where not exists (
     select 1 from sel 
    ) 
    returning color, brightness, size, age 
) 
select color, brightness, size, age 
from ins 
union 
select color, brightness, size, age 
from sel 
2

अपने कॉलम अद्वितीय सूचकांक बाधा में भाग लेते हैं आपको ऐसे उपाय जो संस्करण 9.5 के बाद से avaible है का उपयोग कर सकते हैं:

INSERT INTO mytable (color, brightness, size, age) 
VALUES ('X', 'Y', 'big', 'old') 
ON CONFLICT (color) DO NOTHING; 

(यह मानते हुए कि आप color पर अद्वितीय सूचकांक है)।

डॉक्स गेरे हैं: https://www.postgresql.org/docs/9.5/static/sql-insert.html

+0

यह सवाल का जवाब नहीं देता है, जो पूछता है कि * * * * * * पंक्ति कैसे प्राप्त करें। – Druska

1

यहां मेरे समाधान जोड़ा जा रहा है। यह @Clodoaldo Neto और @ astef के समाधान से अलग है।

WITH ins AS (
    INSERT INTO mytable (color, brightness, size, age) 
    VALUES ('X', 'Y', 'big', 'old') 
    ON CONFLICT (color) DO NOTHING 
    RETURNING * 
) 
SELECT * FROM ins 
UNION 
SELECT * FROM mytable 
    WHERE color = 'X'; 

मैं astef के समाधान मेरी प्रयोजनों के लिए अपर्याप्त पाया: यह "मिलता है या बनाने" के "प्राप्त" भाग प्रदर्शन नहीं करता! यदि मूल्य पहले से मौजूद है, तो कुछ भी नहीं होगा।

कथन के अंत में संघ यह सुनिश्चित करता है कि यदि मान डाला नहीं गया था (क्योंकि यह पहले से मौजूद है) हम अभी भी उस मान को तालिका से पुनर्प्राप्त करते हैं।

+0

मुझे उपर्युक्त के साथ कोई समस्या मिली: यदि कोई संघर्ष है, तो आपकी तालिका का सीरियल आईडी काउंटर क्वेरी के प्रत्येक निष्पादन पर वृद्धि करेगा। यह आदर्श नहीं है। –