2015-05-22 16 views
5

मान लीजिए कि मैं एक राय पोल ऐप बनाने की कोशिश कर रहा हूं, जैसे कि मैं एक राय सर्वेक्षण का एक टेम्पलेट बना सकता हूं, इसे कई अनुभाग/प्रश्न दे सकता हूं, किसी दिए गए प्रश्न की विभिन्न प्रतियों को एकाधिक लोगों को असाइन कर सकता हूं, विभिन्न उपायों (खुशहाली, सफलता, हरे रंग) और इन सभी उपायों पर लागू करने के लिए अलग-अलग प्रश्न अलग-अलग वजन निर्दिष्ट करते हैं।समूह?

कुछ तो जैसे:

CREATE TABLE users (
    id SERIAL NOT NULL PRIMARY KEY 
); 

CREATE TABLE opinion_poll_templates (
    id SERIAL NOT NULL PRIMARY KEY 
); 

CREATE TABLE opinion_poll_instances (
    id SERIAL NOT NULL PRIMARY KEY, 
    template_id INTEGER NOT NULL REFERENCES opinion_poll_templates(id) 
); 

CREATE TABLE section_templates (
    id SERIAL NOT NULL PRIMARY KEY, 
    opinion_poll_id INTEGER NOT NULL REFERENCES opinion_poll_templates(id) 
); 

CREATE TABLE section_instances (
    id SERIAL NOT NULL PRIMARY KEY, 
    opinion_poll_id INTEGER NOT NULL REFERENCES opinion_poll_instances(id), 
    template_id INTEGER NOT NULL REFERENCES section_templates(id) 
); 

CREATE TABLE question_templates (
    id SERIAL NOT NULL PRIMARY KEY, 
    section_id INTEGER NOT NULL REFERENCES section_templates(id) 
); 

CREATE TABLE measure_templates (
    id SERIAL NOT NULL PRIMARY KEY, 
    opinion_poll_id INTEGER NOT NULL REFERENCES opinion_poll_templates(id) 
); 

CREATE TABLE answer_options (
    id SERIAL NOT NULL PRIMARY KEY, 
    question_template_id INTEGER NOT NULL REFERENCES question_templates(id), 
    weight FLOAT8 
); 

CREATE TABLE question_instances (
    id SERIAL NOT NULL PRIMARY KEY, 
    template_id INTEGER NOT NULL REFERENCES question_templates(id), 
    opinion_poll_id INTEGER NOT NULL REFERENCES opinion_poll_instances(id), 
    section_id INTEGER NOT NULL REFERENCES section_instances(id), 
    answer_option_id INTEGER NOT NULL REFERENCES answer_options(id), 
    contributor_id INTEGER 
); 

CREATE TABLE measure_instances (
    id SERIAL NOT NULL PRIMARY KEY, 
    opinion_poll_id INTEGER NOT NULL REFERENCES opinion_poll_instances(id), 
    template_id INTEGER NOT NULL REFERENCES measure_templates(id), 
    total_score INTEGER 
); 

CREATE TABLE scores (
    id SERIAL NOT NULL PRIMARY KEY, 
    question_template_id INTEGER NOT NULL REFERENCES question_templates(id), 
    measure_template_id INTEGER NOT NULL REFERENCES measure_templates(id), 
    score INTEGER NOT NULL 
); 

अब मान लीजिए कि मैं पार सवाल, पार उपयोगकर्ता औसत (एक जनमत सर्वेक्षण करने के लिए सौंपा उपाय प्रति) प्रति measureInstance में दिलचस्पी है?

WITH weighted_score AS (
    SELECT AVG(answer_options.weight), measure_instances.id 
    FROM question_instances 
    INNER JOIN answer_options ON question_instances.template_id = answer_options.question_template_id 
    INNER JOIN scores ON question_instances.template_id = scores.question_template_id 
    INNER JOIN measure_instances ON measure_instances.template_id=scores.measure_template_id 
    WHERE measure_instances.opinion_poll_id = question_instances.opinion_poll_id 
    GROUP BY measure_instances.id 
) 
UPDATE measure_instances 
SET total_score=(SELECT avg FROM weighted_score 
WHERE weighted_score.id = measure_instances.id)*100 
RETURNING total_score; 

ऐसा लगता है कि यह अपेक्षाकृत समूह नहीं है, बल्कि गलत परिणाम उत्पन्न करता है।

परिणाम एक फ्लोट के बजाय एक पूर्णांक क्यों है? नतीजे को मापने के बजाय परिणाम को क्यों समझा जा रहा है? और उनमें से किसी के लिए परिणाम गलत क्यों है?

एक प्रदर्शन: http://sqlfiddle.com/#!15/dcce8/1

संपादित करें: वास्तव में मैं क्या चाहता था समझा माध्यम से काम में, मुझे एहसास हुआ कि मेरी समस्या का स्रोत है कि मैं बस प्रतिशत जोड़ने किया गया था, बल्कि उसके बाद एक प्रतिशत के रूप प्रश्नों के बीच सामान्य था।

मेरे नए और बेहतर एसक्यूएल है:

WITH per_question_percentage AS ( 
    SELECT SUM(answer_options.weight)/COUNT(question_instances.id) percentage, question_templates.id qid, opinion_poll_instances.id oid 
    FROM question_instances 
    INNER JOIN answer_options ON question_instances.answer_option_id = answer_options.id 
    INNER JOIN question_templates ON question_templates.id = question_instances.template_id 
    INNER JOIN opinion_poll_instances ON opinion_poll_instances.id = question_instances.opinion_poll_id 
    GROUP BY question_templates.id, opinion_poll_instances.id 
), max_per_measure AS (
    SELECT SUM(scores.score), measure_instances.id mid, measure_instances.opinion_poll_id oid 
    FROM measure_instances 
    INNER JOIN scores ON scores.measure_template_id=measure_instances.template_id 
    GROUP BY measure_instances.id, measure_instances.opinion_poll_id 
), per_measure_per_opinion_poll AS (
    SELECT per_question_percentage.percentage * scores.score score, measure_instances.id mid, measure_instances.opinion_poll_id oid 
    FROM question_instances 
    INNER JOIN scores ON question_instances.template_id = scores.question_template_id 
    INNER JOIN measure_instances ON measure_instances.template_id = scores.measure_template_id 
    INNER JOIN max_per_measure ON measure_instances.id = max_per_measure.mid 
    INNER JOIN per_question_percentage ON per_question_percentage.qid = question_instances.template_id 
    WHERE measure_instances.opinion_poll_id = question_instances.opinion_poll_id AND question_instances.opinion_poll_id = per_question_percentage.oid 
    GROUP BY measure_instances.id, measure_instances.opinion_poll_id, per_question_percentage.percentage, scores.score 
) 
UPDATE measure_instances 
SET total_score = subquery.result*100 
FROM (SELECT SUM(per_measure_per_opinion_poll.score)/max_per_measure.sum result, per_measure_per_opinion_poll.mid, per_measure_per_opinion_poll.oid 
     FROM max_per_measure, per_measure_per_opinion_poll 
     WHERE per_measure_per_opinion_poll.mid = max_per_measure.mid 
     AND per_measure_per_opinion_poll.oid = max_per_measure.oid 
     GROUP BY max_per_measure.sum, per_measure_per_opinion_poll.mid, per_measure_per_opinion_poll.oid) 
     AS subquery(result, mid, oid) 
WHERE measure_instances.id = subquery.mid 
AND measure_instances.opinion_poll_id = subquery.oid 
RETURNING total_score; 

इस विहित एसक्यूएल है? क्या इस तरह की सीटीई चेनिंग (या अन्यथा) के बारे में मुझे कुछ पता होना चाहिए? क्या एक ही चीज़ हासिल करने का एक और अधिक प्रभावी तरीका है?

+0

प्रश्न 1: 'माप_इंसेस' कुल मिलाकर ''INTEGER' के रूप में परिभाषित किया गया है। प्रश्न 2: यह ** ** सही है 'meas_instances.id' द्वारा समूहित। प्रश्न 3: क्योंकि आप अपने जुड़ने में कुछ गलत करते हैं? सीटीई स्टैंडअलोन के भीतर 'चयन' चलाएं, किसी भी 'AVG'/'GROUP BY' को हटा दें और विवरण पंक्तियों की जांच करें। – dnoeth

उत्तर

1

यह एक टिप्पणी के लिए थोड़ा सा लंबा है।

मुझे प्रश्नों को समझ में नहीं आता है।

परिणाम एक फ्लोट के बजाय एक पूर्णांक क्यों है?

क्योंकि measure_instances.total_score एक पूर्णांक है और returning खंड वापस आ रहा है।

परिणाम उदाहरण के बजाय मापने के उदाहरण को क्यों समूहीकृत नहीं किया जा रहा है?

जब मैं स्वतंत्र रूप से सीटीई चलाता हूं, तो मूल्य 0.45 होते हैं। डेटा और तर्क समान मूल्यों को निर्देशित करते हैं।

और उनमें से किसी के लिए परिणाम गलत क्यों है?

मुझे लगता है कि आपका मतलब है "उन सभी के लिए"। किसी भी मामले में, परिणाम मेरे लिए सही लग रहे हैं।

1

आप अपने डेमो में डेटा के खिलाफ इस क्वेरी चलाते हैं:

SELECT 
    answer_options.weight, measure_instances.id 
FROM 
    question_instances 
INNER JOIN 
    answer_options ON question_instances.template_id = answer_options.question_template_id 
INNER JOIN 
    scores ON question_instances.template_id = scores.question_template_id 
INNER JOIN 
    measure_instances ON measure_instances.template_id=scores.measure_template_id 
WHERE 
    measure_instances.opinion_poll_id = question_instances.opinion_poll_id 
ORDER BY 
    2; 

आप मिल जाएगा:

| weight | id | 
|--------|----| 
| 0.5 | 1 | 
| 0.25 | 1 | 
| 0.25 | 1 | 
| 0.75 | 1 | 
| 0.5 | 1 | 
| 0.75 | 2 | 
| 0.5 | 2 | 
| 0.25 | 2 | 
| 0.5 | 2 | 
| 0.25 | 2 | 

आप हाथ से औसत की गणना हैं, तो आप मिल जाएगा:

आईडी के लिए = 1 ==> 0.5 + 0.25 + 0.25 + 0.75 + 0.5 = 2.25 ==> 2.25/5 = 0.45
के लिए आईडी = 2 ==> 0,75 + 0,5 + 0,25 + 0,5 + 0,25 = 2,25 ==> 2,25/5 = 0,45

मुझे ऐसा लगता है, कि इस क्वेरी पूरी तरह से काम कर रहा है।

कृपया बताएं कि ये परिणाम आपके लिए क्यों गलत हैं, और आप उपरोक्त डेटा और क्वेरी से क्या प्राप्त करने की उम्मीद करते हैं?

+0

मुझे यह समझाने के लिए धन्यवाद देने के लिए धन्यवाद। ऐसा करने में, मैं वास्तव में एक समाधान पर पहुंचा हूं। मेरी समस्या यह थी कि मैं अपने परिणामों को उपायों में सामान्य नहीं कर रहा था। एक अद्यतन (संपादन में) के लिए मेरा प्रश्न देखें। –