crosstab()
दो पैरामीटर के साथ कार्य करें।
इस तरह काम करना चाहिए, 2012 के लिए मान प्राप्त करने के लिए:
SELECT * FROM crosstab(
$$SELECT testname, to_char(last_update, 'mon_YYYY'), count(*)::int AS ct
FROM tests
WHERE current_status = 'FAILED'
AND last_update >= '2012-01-01 0:0'
AND last_update < '2013-01-01 0:0' -- proper date range!
GROUP BY 1,2
ORDER BY 1,2$$
,$$VALUES
('jan_2012'::text), ('feb_2012'), ('mar_2012')
, ('apr_2012'), ('may_2012'), ('jun_2012')
, ('jul_2012'), ('aug_2012'), ('sep_2012')
, ('oct_2012'), ('nov_2012'), ('dec_2012')$$)
AS ct (testname text
, jan_2012 int, feb_2012 int, mar_2012 int
, apr_2012 int, may_2012 int, jun_2012 int
, jul_2012 int, aug_2012 int, sep_2012 int
, oct_2012 int, nov_2012 int, dec_2012 int);
इस संबंधित प्रश्न के अंतर्गत विस्तृत विवरण प्राप्त करें।
<स्ट्राइक>मैंने टेस्ट नहीं किया।स्ट्राइक> जैसा कि @ क्रेग ने टिप्पणी की, नमूना मूल्यों ने मदद की होगी।
अब मेरे अपने परीक्षण मामले के साथ परीक्षण किया गया।
शून्य मान प्रदर्शित न करें
मुख्य समस्या (बिना पंक्तियों के महीने बिल्कुल भी दिखाई नहीं देंगे) crosstab()
द्वारा टाला जाता है दो मापदंडों के साथ कार्य करें।
आप COALESCE
. का उपयोग नहीं कर सकते आंतरिक क्वेरी में, क्योंकि NULL
मान crosstab()
. द्वारा डाले जाते हैं अपने आप। आप कर सकते हैं ...
SELECT testname
,COALESCE(jan_2012, 0) AS jan_2012
,COALESCE(feb_2012, 0) AS feb_2012
,COALESCE(mar_2012, 0) AS mar_2012
, ...
FROM (
-- query from above)
) x;
<एच4>2. LEFT JOIN
महीनों की पूरी सूची के लिए प्राथमिक क्वेरी।
इस मामले में, आपको परिभाषा के अनुसार दूसरे पैरामीटर की आवश्यकता नहीं है।
बड़ी रेंज के लिए आप generate_series()
का उपयोग कर सकते हैं। मान बनाने के लिए।
SELECT * FROM crosstab(
$$SELECT t.testname, m.mon, count(x.testname)::int AS ct
FROM (
VALUES
('jan_2012'::text), ('feb_2012'), ('mar_2012')
,('apr_2012'), ('may_2012'), ('jun_2012')
,('jul_2012'), ('aug_2012'), ('sep_2012')
,('oct_2012'), ('nov_2012'), ('dec_2012')
) m(mon)
CROSS JOIN (SELECT DISTINCT testname FROM tests) t
LEFT JOIN (
SELECT testname
,to_char(last_update, 'mon_YYYY') AS mon
FROM tests
WHERE current_status = 'FAILED'
AND last_update >= '2012-01-01 0:0'
AND last_update < '2013-01-01 0:0' -- proper date range!
) x USING (mon)
GROUP BY 1,2
ORDER BY 1,2$$
)
AS ct (testname text
, jan_2012 int, feb_2012 int, mar_2012 int
, apr_2012 int, may_2012 int, jun_2012 int
, jul_2012 int, aug_2012 int, sep_2012 int
, oct_2012 int, nov_2012 int, dec_2012 int);
नमूना डेटा के साथ परीक्षण केस
यहां कुछ नमूना डेटा के साथ एक परीक्षण मामला है जो ओपी प्रदान करने में विफल रहा। मैंने इसका परीक्षण करने और इसे काम करने के लिए इस्तेमाल किया।
CREATE TEMP TABLE tests (
id bigserial PRIMARY KEY
,testname text NOT NULL
,last_update timestamp without time zone NOT NULL DEFAULT now()
,current_status text NOT NULL
);
INSERT INTO tests (testname, last_update, current_status)
VALUES
('foo', '2012-12-05 21:01', 'FAILED')
,('foo', '2012-12-05 21:01', 'FAILED')
,('foo', '2012-11-05 21:01', 'FAILED')
,('bar', '2012-02-05 21:01', 'FAILED')
,('bar', '2012-02-05 21:01', 'FAILED')
,('bar', '2012-03-05 21:01', 'FAILED')
,('bar', '2012-04-05 21:01', 'FAILED')
,('bar', '2012-05-05 21:01', 'FAILED');