2015-07-14 18 views
9

पोस्टग्रेएसक्यूएल 9.4 विंडो फ़ंक्शंस में FILTER का नया विकल्प प्रसंस्करण के लिए विंडो फ्रेम का उप-सेट चुनने के लिए नया विकल्प है। दस्तावेज इसका उल्लेख करता है, लेकिन कोई नमूना प्रदान नहीं करता है। एक ऑनलाइन खोज 2ndQuadrant सहित कुछ नमूने उत्पन्न करती है, लेकिन जो कुछ मैंने पाया वह लगातार अभिव्यक्तियों के साथ मामूली उदाहरण थे। जो मैं खोज रहा हूं वह एक फ़िल्टर अभिव्यक्ति है जिसमें वर्तमान पंक्ति का मूल्य शामिल है।विंडो फ़ंक्शन के फ़िल्टर खंड में वर्तमान पंक्ति का संदर्भ

मान लें मैं कॉलम का एक समूह, जिनमें से एक date प्रकार की है के साथ एक मेज है:

col1 | col2 |  dt 
------------------------ 
    1 | a | 2015-07-01 
    2 | b | 2015-07-03 
    3 | c | 2015-07-10 
    4 | d | 2015-07-11 
    5 | e | 2015-07-11 
    6 | f | 2015-07-13 
...

एक विंडो पूरे मेज पर date पर प्रसंस्करण के लिए परिभाषा तुच्छता का निर्माण किया है: WINDOW win AS (ORDER BY dt)

मुझे यह जानने में दिलचस्पी है कि वर्तमान पंक्ति (समावेशी) से 4 दिन पहले, कितनी पंक्तियां मौजूद हैं।

count(*) FILTER (WHERE current_row.dt - dt <= 4) OVER win

लेकिन मैं कैसे निर्दिष्ट करूँ current_row.dt (एक बेहतर वाक्य रचना की कमी के लिए):

col1 | col2 |  dt  | count 
-------------------------------- 
    1 | a | 2015-07-01 | 1 
    2 | b | 2015-07-03 | 2 
    3 | c | 2015-07-10 | 1 
    4 | d | 2015-07-11 | 3 
    5 | e | 2015-07-11 | 3 
    6 | f | 2015-07-13 | 4 
...

खिड़की कार्यों का FILTER खंड स्वाभाविक पसंद की तरह लगता है: तो मैं इस उत्पादन उत्पन्न करने के लिए करना चाहते हैं? क्या यह भी संभव है?

यदि यह संभव नहीं है, तो क्या विंडो फ्रेम में date श्रेणियां चुनने के अन्य तरीके हैं? फ्रेम विनिर्देशन कोई मदद नहीं है क्योंकि यह सभी पंक्ति-आधारित है।

मुझे उप-प्रश्नों का उपयोग करके वैकल्पिक समाधान में रूचि नहीं है, इसे विंडो प्रसंस्करण पर आधारित होना चाहिए।

+0

दिलचस्प समस्या। नियमित रूप से पोस्टग्रेस के रूप में आपको एक टेबल परिभाषा (या बेहतर अभी तक, एक पूर्ण 'तालिका बनाएं' स्क्रिप्ट) –

+0

@ErwinBrandstetter प्रदान करना चाहिए, यह ऐसा कुछ है जो "फीचर अनुरोध" के रूप में फ़्लैगिंग की योग्यता प्राप्त करेगा? मेरे लिए यह वर्तमान पंक्ति में मौजूद कुछ स्थितियों के आधार पर विंडो फ्रेम को फ़िल्टर करने में सक्षम होने के लिए काफी मूल्यवान प्रतीत होता है। – Patrick

+0

हां, यह विभिन्न समस्याओं के लिए उपयोगी होगा, मैंने SO पर कई संबंधित प्रश्न देखे हैं। मुझे डर है कि कार्यान्वयन में प्रमुख बदलावों के कारण इस सुविधा को बहुत सारे काम की आवश्यकता होगी, लेकिन यह सुविधा में सार्वजनिक रुचि के दस्तावेज को चोट नहीं पहुंचाएगा। गायब 'रेंज के बीच ... सीमा निर्धारण/अनुसरण करने वाली सुविधा' से संबंधित लगता है जो पहले से ही [टूडो विकी में प्रलेखित है] (https://wiki.postgresql.org/wiki/Todo#Window_Functions) –

उत्तर

5

आप वास्तव में पंक्तियों को एकत्रित नहीं कर रहे हैं, इसलिए नया कुल FILTER खंड सही टूल नहीं है। एक विंडो फ़ंक्शन इसके जैसा अधिक है, एक समस्या बनी हुई है, हालांकि: frame definition विंडो की वर्तमान पंक्ति के मान पर निर्भर नहीं हो सकता है। यह केवल ROWS खंड से पहले या निम्नलिखित पंक्तियों की एक निश्चित संख्या को गिन सकता है।

उस काम को करने के लिए, प्रति दिन कुल संख्या और LEFT JOIN सीमा के पूर्ण सेट में।

SELECT t.*, ct.ct_last4days 
FROM (
    SELECT *, sum(ct) OVER (ORDER BY dt ROWS 3 PRECEDING) AS ct_last4days 
    FROM (
     SELECT generate_series(min(dt), max(dt), interval '1 day')::date AS dt 
     FROM tbl t1 
    ) d 
    LEFT JOIN (SELECT dt, count(*) AS ct FROM tbl GROUP BY 1) t USING (dt) 
    ) ct 
JOIN tbl t USING (dt); 

विधवा फ्रेम परिभाषा आमतौर पर कार्यों में ORDER BY dt छोड़ना, क्योंकि आदेश सबक्वेरी में generate_series() से खत्म किया जाता है: तो फिर तुम एक खिड़की समारोह आवेदन कर सकते हैं। लेकिन स्पष्ट ORDER BY के बिना SQL मानक में कोई गारंटी नहीं है और यह अधिक जटिल प्रश्नों को तोड़ सकता है।

SQL Fiddle.

संबंधित:

+0

जब 'फ़िल्टर' खंड 'ओवर' खंड की उपस्थिति में कुल कार्यों पर लागू होता है [* विंडो फ़ंक्शन के रूप में कार्य करें (...) अन्यथा वे नियमित योग के रूप में कार्य करते हैं *] (http://www.postgresql.org/docs/current/static/ फ़ंक्शंस-window.html) ताकि आपकी प्रस्तुति को अमान्य कर दिया जाए, अगर मैं दोनों दस्तावेज और सही ढंग से समझता हूं। एक समाधान समाधान और विस्तार से सावधानीपूर्वक ध्यान देने के लिए स्वीकृत, लेकिन केवल उप-प्रश्नों पर निर्भरता के लिए अनिच्छुक रूप से, जिसके लिए आप स्पष्ट रूप से दोष नहीं दे रहे हैं। – Patrick

+0

@ पैट्रिक: कुल कार्य (कर सकते हैं) पंक्तियों को तब्दील कर सकते हैं, जबकि विंडो फ़ंक्शन नहीं करते हैं। आप स्पष्ट रूप से पंक्तियों को फोल्ड नहीं करना चाहते हैं, इसलिए आप खिड़की के कार्यों के दायरे में हैं। 'फ़िल्टर' खंड कुल कार्यों के लिए विंडो फ़ंक्शंस की कुछ विशेषताओं को लागू करता है, लेकिन आपको किसी भी विंडो फ़ंक्शन की आवश्यकता होती है। –

1

मुझे नहीं लगता कि किसी भी वाक्य रचना एक अभिव्यक्ति में "वर्तमान पंक्ति" का मतलब है कि वहाँ है । पोस्टग्रेज़ के लिए gram.y फ़ाइल फ़िल्टर फ़िल्टर केवल एक a_expr लेती है, जो केवल सामान्य अभिव्यक्ति खंड है। वहां विंडो फ़ंक्शंस या अभिव्यक्ति में फ़िल्टर क्लॉज के लिए विशिष्ट नहीं है। जहां तक ​​मुझे मिल सकता है, विंडो खंड में एकमात्र वर्तमान पंक्ति धारणा विंडो फ्रेम सीमाओं को निर्दिष्ट करने के लिए है। मुझे नहीं लगता कि यह आपको प्राप्त करता है जो आप चाहते हैं।

यह आप एक संलग्न क्वेरी से कुछ कर्षण मिल सकता है कि संभव है:

http://www.postgresql.org/docs/current/static/sql-expressions.html

एक समग्र अभिव्यक्ति एक सबक्वेरी में दिखाई देता है (देखें धारा 4.2.11 और धारा 9.22), कुल आमतौर पर सबक्वायरी की पंक्तियों पर मूल्यांकन किया जाता है। लेकिन एक अपवाद तब होता है जब कुल तर्क (और फ़िल्टर_क्लोज़ यदि कोई हो) में केवल बाहरी-स्तर चर होते हैं: कुल निकटतम बाहरी स्तर से संबंधित है, और उस क्वेरी की पंक्तियों पर मूल्यांकन किया गया है।

लेकिन यह मेरे लिए स्पष्ट नहीं है कि कैसे।

संबंधित मुद्दे