आप ज़्यादातर लागत को CTE में एक ही मुख्य क्वेरी में बंडल कर सकते हैं
और परिणाम को कई बार पुन:उपयोग करें।
यह तीन स्तंभों वाली एकल पंक्ति returns देता है प्रत्येक के नाम पर type
(अनुरोध के अनुसार टिप्पणी में
):
WITH cte AS (
SELECT cai.id, cai.activity_id, cas.key, cas.value
FROM common_activityinstance cai
JOIN common_activityinstance_settings s ON s.activityinstance_id = cai.id
JOIN common_activitysetting cas ON cas.id = s.id
WHERE cai.end_time::date = '2015-09-12' -- problem?
AND cai.activity_type = 'QZ'
AND (cas.key = 'disable_student_nav' AND cas.value IN ('True', 'False') OR
cas.key = 'pacing' AND cas.value IN ('student', 'teacher'))
)
SELECT *
FROM (
SELECT count(*) AS spf
FROM (
SELECT c.id
FROM cte c
JOIN quizzes_quiz q ON q.id = c.activity_id
WHERE q.name <> 'Exit Ticket Quiz'
AND (c.key, c.value) IN (('disable_student_nav', 'True')
, ('pacing', 'student'))
GROUP BY 1
HAVING count(*) = 2
) sub
) spf
, (
SELECT count(key = 'disable_student_nav' AND value = 'False' OR NULL) AS spn
, count(key = 'pacing' AND value = 'teacher' OR NULL) AS tp
FROM cte
) spn_tp;
पोस्टग्रेज 9.3 के लिए काम करना चाहिए। Postgres 9.4 में आप नए समुच्चय FILTER
. का उपयोग कर सकते हैं खंड:
count(*) FILTER (WHERE key = 'disable_student_nav' AND value = 'False') AS spn
, count(*) FILTER (WHERE key = 'pacing' AND value = 'teacher') AS tp
दोनों सिंटैक्स प्रकारों के लिए विवरण:
problem?
. के रूप में चिह्नित शर्त cai.end_time
. के डेटा प्रकार के आधार पर बड़ी प्रदर्शन समस्या हो सकती है . एक के लिए, यह sargable नहीं है
. और अगर यह एक timestamptz
है प्रकार, अभिव्यक्ति को अनुक्रमित करना कठिन है, क्योंकि परिणाम सत्र की वर्तमान समय क्षेत्र सेटिंग पर निर्भर करता है - जो अलग-अलग समय क्षेत्रों में निष्पादित होने पर अलग-अलग परिणाम भी दे सकता है।
तुलना करें:
- एक ही टेबल से दो क्वेरी को कम करें
- अब से घंटे घटाएं( ) फ़ंक्शन
- टाइमज़ोन को पूरी तरह से अनदेखा करना रेल और पोस्टग्रेएसक्यूएल
आपको बस उस समय क्षेत्र का नाम देना है जो आपकी तिथि को परिभाषित करने वाला है। उदाहरण के तौर पर विएना में अपना समय क्षेत्र लेते हुए:
WHERE cai.end_time >= '2015-09-12 0:0'::timestamp AT TIME ZONE 'Europe/Vienna'
AND cai.end_time < '2015-09-13 0:0'::timestamp AT TIME ZONE 'Europe/Vienna'
आप सरल timestamptz
प्रदान कर सकते हैं मूल्य भी। आप बस इतना ही कर सकते हैं:
WHERE cai.end_time >= '2015-09-12'::date
AND cai.end_time < '2015-09-12'::date + 1
लेकिन पहला संस्करण वर्तमान समय क्षेत्र सेटिंग पर निर्भर नहीं करता है।
उपरोक्त लिंक में विस्तृत विवरण।
अब क्वेरी आपकी अनुक्रमणिका का उपयोग कर सकती है और यदि आपकी तालिका में कई अलग-अलग दिन हैं तो यह बहुत तेज़ होनी चाहिए।