2012-12-07 20 views
7
में एक प्रश्न के परिणामों के साथ एक कॉलम अपडेट कर रहा है

मैं PostgreSQL 9.2 में निम्न तालिका जो समय टिकटों शामिल हैं: (समय क्षेत्र के बिना टाइमस्टैम्प)PostgreSQL

gid [पी] (bigserial), timestamp_mes, time_diff (अंतराल)
1, 2012-01-23 11:03:40, खाली
2, 2012-01-23 11:03:42, खाली
3, 2012-01-23 11:03:44, खाली

मैंने एक अंतराल कॉलम (time_diff) जोड़ा है और टी के परिणामस्वरूप समय अंतर मानों को भरना चाहता हूं उसकी क्वेरी:

SELECT timestamp_mes - lag(timestamp_mes, 1) 
over (order by timestamp_mes) as diff 
from gc_entretien.trace order by timestamp_mes 

मैं time_diff स्तंभ अद्यतन करने के लिए निम्न क्वेरी की कोशिश की है, कोई सफलता के साथ:

UPDATE gc_entretien.trace set time_diff = 
(SELECT trace.timestamp_mes - lag(trace.timestamp_mes, 1) 
over (order by trace.timestamp_mes) 
from gc_entretien.trace order by timestamp_mes); 

यह एक त्रुटि में परिणाम है:

ERROR: more than one row returned by a subquery used as an expression

मैं कैसे आगे बढ़ना चाहिए टाइम फर्क क्वेरी के परिणामस्वरूप मान_डिफ कॉलम को अपडेट करने के लिए? क्योंकि आपके सबक्वेरी कई परिणाम देता है

+1

अपने ऐप के तर्क के बारे में निश्चित नहीं है, लेकिन चयन संभवतः अधिक पंक्तियां देता है जो त्रुटि का कारण बनता है एस में असाइन करना इंजेल कॉलम (जैसे आप अपने 'अपडेट' में करते हैं) ... यदि परिणाम आपकी 'SELECT' में लौटाई गई पहली पंक्ति में है, तो असाइनमेंट को संभव बनाने के लिए' LIMIT 1' का उपयोग करें। वैसे भी चयन सही ढंग से डिजाइन नहीं प्रतीत होता है। –

+0

@ कमिलरोट - इसमें एक समस्या है; क्योंकि सबक्वायरी (वर्तमान में) असंबद्ध है, 'LIMIT 1' केवल शीर्ष पंक्ति, अवधि को वापस कर देगा, न कि वर्तमान पंक्ति के साथ कुछ भी करने के लिए। –

+0

@ क्लॉकवर्क-म्यूज़न सही, यही कारण है कि मैं कहता हूं कि यह सही ढंग से डिज़ाइन की गई क्वेरी नहीं है।पहले @jatobat को एक प्रश्न को वापस करने की आवश्यकता होती है (जिसे वह एप्लिकेशन तर्क के अनुसार चाहिए) और उसके बाद इसे 'UPDATE' क्वेरी' में subquery के रूप में रखें ... सामान्य परिदृश्य तालिका से कुछ पहचानकर्ता/मानों का उपयोग करना है (resp पंक्ति पंक्ति) subquery 'WHERE' खंड में शर्त (ओं) के रूप में subquery में अद्यतन किया जा रहा है। लेकिन स्पष्ट रूप से कहा: मैं ऐप के तर्क को समझ नहीं पा रहा हूं और यहां तक ​​कि इसे समझना नहीं चाहता :-) –

उत्तर

22

कुछ ली ke इस:

with new_values as (
    SELECT gid, 
      timestamp_mes - lag(timestamp_mes, 1) over (order by timestamp_mes) as diff 
    from gc_entretien.trace 
) 
update gc_entretien.trace as tr 
    set time_diff = nv.diff 
from new_values nv 
where nv.gid = tr.gid; 
+0

+1। यह मेरे लिए सही लग रहा है, और मुझे 4 मिनट तक हराया। कभी भी 'के साथ ... AS ...' के अस्तित्व के बारे में कभी नहीं पता था। ठंडा। :) –

+0

@ मार्क आर्मरी: इसे "सामान्य तालिका अभिव्यक्ति" कहा जाता है, और 9.1 के बाद से इसका उपयोग डीएमएल कथन के लिए भी किया जा सकता है (इससे पहले इसे सामान्य चयन विवरणों के लिए उपयोग किया जा सकता है - रिकर्सिव क्वेरीज सहित) –

+0

यदि आप इसे कर रहे हैं टी-एसक्यूएल ऐसा लगता है कि आप अद्यतन तालिका को उपनाम नहीं कर सकते हैं। यदि आप टेबल नाम का स्पष्ट रूप से उपयोग करते हैं (इस मामले में tr की बजाय) यह काम करेगा हालांकि। –

1

वास्तव में आपको यह त्रुटि हो रही है,

मैं तो आपकी क्वेरी को समझने में सक्षम नहीं हूँ,

मैं आप इसे हल करने के लिए एक उदाहरण दे देंगे,

update table t1 set time_diff= select *your_operation* from table t2 where t1.id=t2.id 

यहाँ: -your_operation, समय अंतर को खोजने का तर्क का मतलब

+0

हां, यह सामान्य रूप है जो उसे करने की ज़रूरत है ... शायद बाकी के बाकी हिस्सों को भरें क्वेरी? –

+0

यह उत्तर पोस्टग्रेएसक्यूएल 9.0.1 के साथ समस्या होने के लिए मेरे लिए काम किया। धन्यवाद। – Ambran

3

आप सीधे, एक अद्यतन में एक खिड़की समारोह का उपयोग नहीं कर सकते हैं तो आप के बजाय एक उप चयन में इसका इस्तेमाल करने की जरूरत है - जो आप नहीं किया है। हालांकि, जिस तरह से आपने अपने UPDATE में उस उप-चयन का उपयोग करने का प्रयास किया है वह वैध वाक्यविन्यास नहीं है।

http://www.postgresql.org/docs/9.2/static/sql-update.html

कि आप क्या करना चाहते हैं के लिए सही सिंटैक्स है:

UPDATE gc_entretien.trace t 
SET time_diff = subquery.diff 
FROM (SELECT {{SomeUniqueId}}, 
      timestamp_mes - lag(timestamp_mes, 1) over (order by timestamp_mes) as diff 
     FROM gc_entretien.trace order by timestamp_mes) AS subquery 
WHERE t.{{SomeUniqueId}} = subquery.{{SomeUniqueId}} 
के रूप में यहाँ Postgres डॉक्स से समझाया आप अपने अद्यतन की FROM खंड में उप चयन लगाने की जरूरत है

जाहिर है, आपको कुछ अद्वितीय आईडी के कॉलम नाम में प्रतिस्थापित करने की आवश्यकता होगी, जहां आपकी पंक्तियां हैं {{SomeUniqueId}}