/ / PostgreSQL Crosstab उत्पन्न_ स्तंभों के लिए हफ्तों की - पोस्टग्रेशकल, क्रॉसस्टैब, जेनरेट-सीरीज़

PostgreSQL Crosstab कॉलम के लिए हफ्तों की जेनरेटरीज - पोस्टग्रेस्क्ल, क्रॉसस्टैब, जेनरेट-सीरीज़

"समय प्रविष्टियों" की एक तालिका से मैं प्रत्येक उपयोगकर्ता के लिए साप्ताहिक योगों की एक रिपोर्ट बनाने की कोशिश कर रहा हूं।

तालिका का नमूना:

+-----+---------+-------------------------+--------------+
| id  | user_id | start_time              | hours_worked |
+-----+---------+-------------------------+--------------+
| 997 | 6       | 2018-01-01 03:05:00 UTC | 1.0          |
| 996 | 6       | 2017-12-01 05:05:00 UTC | 1.0          |
| 998 | 6       | 2017-12-01 05:05:00 UTC | 1.5          |
| 999 | 20      | 2017-11-15 19:00:00 UTC | 1.0          |
| 995 | 6       | 2017-11-11 20:47:42 UTC | 0.04         |
+-----+---------+-------------------------+--------------+

अभी मैं निम्नलिखित चला सकता हूं और मूल रूप से मुझे जो चाहिए वह मिलेगा

SELECT COALESCE(SUM(time_entries.hours_worked),0) AS total,
time_entries.user_id,
week::date

--Using generate_series here to account for weeks with no time entries when
--doing the join

FROM generate_series( (DATE_TRUNC("week", "2017-11-01 00:00:00"::date)),
(DATE_TRUNC("week", "2017-12-31 23:59:59.999999"::date)),
interval "7 day") as week LEFT JOIN time_entries
ON DATE_TRUNC("week", time_entries.start_time) = week

GROUP BY week, time_entries.user_id
ORDER BY week

यह वापस आ जाएगा

+-------+---------+------------+
| total | user_id | week       |
+-------+---------+------------+
| 14.08 | 5       | 2017-10-30 |
| 21.92 | 6       | 2017-10-30 |
| 10.92 | 7       | 2017-10-30 |
| 14.26 | 8       | 2017-10-30 |
| 14.78 | 10      | 2017-10-30 |
| 14.08 | 13      | 2017-10-30 |
| 15.83 | 15      | 2017-10-30 |
| 8.75  | 5       | 2017-11-06 |
| 10.53 | 6       | 2017-11-06 |
| 13.73 | 7       | 2017-11-06 |
| 14.26 | 8       | 2017-11-06 |
| 19.45 | 10      | 2017-11-06 |
| 15.95 | 13      | 2017-11-06 |
| 14.16 | 15      | 2017-11-06 |
| 1.00  | 20      | 2017-11-13 |
| 0     |         | 2017-11-20 |
| 2.50  | 6       | 2017-11-27 |
| 0     |         | 2017-12-04 |
| 0     |         | 2017-12-11 |
| 0     |         | 2017-12-18 |
| 0     |         | 2017-12-25 |
+-------+---------+------------+

हालांकि, विशेष रूप से पार्स करना मुश्किल हैजब एक सप्ताह के लिए कोई डेटा नहीं है। मैं जो चाहूंगा वह एक धुरी या क्रॉसस्टैब टेबल है जहां सप्ताह कॉलम और पंक्तियां उपयोगकर्ता हैं। और प्रत्येक से नल शामिल करने के लिए (उदाहरण के लिए यदि उपयोगकर्ता में कोई प्रविष्टि नहीं थी। सप्ताह या किसी भी उपयोगकर्ता से प्रविष्टियों के बिना सप्ताह)।

कुछ इस तरह

+---------+---------------+--------------+--------------+
| user_id | 2017-10-30    | 2017-11-06   | 2017-11-13   |
+---------+---------------+--------------+--------------+
| 6       | 4.0           | 1.0          | 0            |
| 7       | 4.0           | 1.0          | 0            |
| 8       | 4.0           | 0            | 0            |
| 9       | 0             | 1.0          | 0            |
| 10      | 4.0           | 0.04         | 0            |
+---------+---------------+--------------+--------------+

मैं "ऑनलाइन देख रहा हूँ और ऐसा लगता है कि" गतिशील रूप से "क्रॉसस्टैब के लिए कॉलम की एक सूची तैयार कर रहा है कठिन। मैं उन्हें कठिन कोड नहीं, जो तारीखों के लिए वैसे भी अजीब लगता है। या कुछ इस तरह का उपयोग करें सप्ताह संख्या के साथ मामला.

क्या मुझे इसके अलावा किसी और उपाय की तलाश करनी चाहिएcrosstab? अगर मुझे लगता है कि मुझे लगता है कि काफी अच्छा होगा सभी नल सहित प्रत्येक उपयोगकर्ता के लिए सप्ताह की श्रृंखला मिल सकती है। ऐसा लगता है कि अभी मेरी जॉइन स्ट्रेटेजी इन्न "टी रिटर्निंग" है।

उत्तर:

जवाब के लिए 0 № 1

व्यक्तिगत रूप से मैं एक दिनांक आयाम तालिका और का उपयोग करेगाक्वेरी के आधार के रूप में उस तालिका का उपयोग करें। मुझे इन प्रकार की गणनाओं के लिए सारणीबद्ध डेटा का उपयोग करना बहुत आसान लगता है क्योंकि यह एसक्यूएल की ओर जाता है जो "पढ़ने और बनाए रखने में आसान है।" पोस्टग्रेएसक्यूएल में दिनांक आयाम तालिका बनाने पर एक बढ़िया लेख है। https://medium.com/@duffn/creating-a-date-dimension-table-in-postgresql-af3f8e2941ac, हालांकि आप इस तालिका के बहुत सरल संस्करण के साथ दूर हो सकते हैं।

अंतत: आप जो करते हैं वह आधार के रूप में दिनांक तालिका का उपयोग करेगा SELECT cols FROM table गणना बनाने के लिए अनुभाग और फिर उस के खिलाफ शामिल हों, या संभवतः कॉमन टेबल एक्सप्रेशंस का उपयोग करें।

मैं इसका समाधान लिखूंगा कि यदि आप यह प्रदर्शित करना चाहते हैं कि आप ऐसी क्वेरी कैसे बना सकते हैं।