मैं उन परिणामों को प्राप्त करने के लिए किसी भी साफ तरीके के बारे में नहीं सोच सकता जो आप ActiveRecord के माध्यम से कर रहे हैं लेकिन यह SQL में बहुत आसान है।
आप वास्तव में केवल deal_goal
खोलने का प्रयास कर रहे हैं सरणियाँ और खुले सरणियों के आधार पर एक हिस्टोग्राम बनाएँ। आप इसे सीधे SQL में इस तरह व्यक्त कर सकते हैं:
with expanded_deals(id, goal) as (
select id, unnest(deal_goal)
from deals
)
select goal, count(*) n
from expanded_deals
group by goal
और यदि आप सभी चार लक्ष्यों को शामिल करना चाहते हैं, भले ही वे किसी भी deal_goal
में न दिखाई दें s तो ऐसा कहने के लिए बस एक LEFT JOIN में टॉस करें:
with
all_goals(goal) as (
values ('traffic'),
('acquisition'),
('branding'),
('qualification')
),
expanded_deals(id, goal) as (
select id, unnest(deal_goal)
from deals
)
select all_goals.goal goal,
count(expanded_deals.id) n
from all_goals
left join expanded_deals using (goal)
group by all_goals.goal
एसक्यूएल डेमो :http://sqlfiddle.com/#!15/3f0af/20
उनमें से किसी एक को select_rows<में फेंक दें /कोड>
कॉल करें और आपको अपना डेटा मिल जाएगा:
Deal.connection.select_rows(%q{ SQL goes here }).each do |row|
goal = row.first
n = row.last.to_i
#....
end
शायद यहाँ बहुत कुछ चल रहा है जिससे आप परिचित नहीं हैं इसलिए मैं थोड़ा समझाता हूँ।
सबसे पहले, मैं चयनों को सरल बनाने के लिए WITH और कॉमन टेबल एक्सप्रेशंस (CTE) का उपयोग कर रहा हूं। साथ में एक मानक SQL सुविधा है जो आपको SQL मैक्रोज़ या किसी प्रकार की इनलाइन अस्थायी तालिकाएँ बनाने की अनुमति देता है। अधिकांश भाग के लिए, आप सीटीई ले सकते हैं और इसे सीधे उस क्वेरी में छोड़ सकते हैं जहां उसका नाम है:
with some_cte(colname1, colname2, ...) as ( some_pile_of_complexity )
select * from some_cte
इस प्रकार है:
select * from ( some_pile_of_complexity ) as some_cte(colname1, colname2, ...)
सीटीई एक अत्यधिक जटिल क्वेरी/विधि को छोटे और समझने में आसान टुकड़ों में पुन:सक्रिय करने का SQL तरीका है।
अननेस्ट
एक सरणी फ़ंक्शन है जो एक सरणी को अलग-अलग पंक्तियों में अनपैक करता है। तो अगर आप कहते हैं unnest(ARRAY[1,2])
, आपको दो पंक्तियाँ वापस मिलती हैं:1
और 2
।
VALUES PostgreSQL में, इनलाइन स्थिर तालिकाओं को कम या ज्यादा करने के लिए उपयोग किया जाता है। आप सामान्य तालिका का उपयोग करने के लिए कहीं भी VALUES का उपयोग कर सकते हैं, यह केवल कुछ सिंटैक्स नहीं है जिसे आप INSERT में डेटाबेस को यह बताने के लिए फेंकते हैं कि कौन से मान डालने हैं। इसका मतलब है कि आप इस तरह की बातें कह सकते हैं:
select * from (values (1), (2)) as dt
और पंक्तियाँ प्राप्त करें 1
और 2
बाहर। उस VALUES को CTE में डालने से चीजें अच्छी और पठनीय हो जाती हैं और यह अंतिम क्वेरी में किसी भी पुरानी तालिका की तरह दिखती है।