एक एसक्यूएल-y रास्ता
पहले, ताकि रेल-विशिष्ट वाक्यविन्यास नहीं करता सिर्फ एसक्यूएल में समस्या का समाधान, चलो हमें चाल नहीं है। Finding duplicate values in a SQL Table
किलोमीटर से जवाब (दूसरा ऊपर से, इस समय गैर checkmarked,) उनकी आईडी के साथ-साथ सभी दोहराया रिकॉर्ड लौटने के अपने मानदंडों को पूरा करती:
यह तो सवाल यह एक बहुत स्पष्ट समानांतर है। मैं अपने तालिका से मिलान के किलोमीटर के एसक्यूएल संशोधित कर लिया है ...
SELECT
m.id, m.title
FROM
movies m
INNER JOIN (
SELECT
title, COUNT(*) AS CountOf
FROM
movies
GROUP BY
title
HAVING COUNT(*)>1
) dupes
ON
m.title=dupes.title
भाग INNER JOIN ()
अंदर अनिवार्य रूप से है क्या आप पहले से ही तैयार किया है। डुप्लिकेट शीर्षक और गणना की एक समूहीकृत तालिका। यह चाल JOIN
है जो इसे 0mतालिका में आईएनजी में डालती है, जो किसी भी फिल्म को बाहर कर देगी जिसमें डुप्लिकेट की क्वेरी में मिलान नहीं है।
रेल में उत्पन्न करना इतना मुश्किल क्यों है? सबसे कठिन हिस्सा यह है कि, क्योंकि हम JOIN
आईएन movies
से movies
हैं, हमें उपरोक्त मेरी क्वेरी में तालिका उपनाम (m
और dupes
बनाना होगा)।
अफसोस की बात है, यह रेल इन उपनामों को घोषित करने के किसी भी साफ तरीके प्रदान नहीं करता है। कुछ संदर्भ:
सौभाग्य से, हम में हाथ एसक्यूएल मिल गया है के बाद से, हम .find_by_sql
विधि का उपयोग कर सकते हैं ...
Movie.find_by_sql("SELECT m.id, m.title FROM movies m INNER JOIN (SELECT title, COUNT(*) FROM movies GROUP BY title HAVING COUNT(*)>1) dupes ON m.first=.first")
क्योंकि हम Movie.find_by_sql
, ActiveRecord कॉल कर रहे हैं मानता है कि हमारे हाथ से लिखे गए एसक्यूएल को Movie
ऑब्जेक्ट्स में बंडल किया जा सकता है। यह किसी भी मालिश या उत्पन्न नहीं करता है, जो हमें अपने उपनाम करने देता है।
इस दृष्टिकोण की इसकी कमियां हैं। यह एक सरणी देता है, न कि ActiveRecord Relation, जिसका अर्थ है कि इसे अन्य क्षेत्रों के साथ जंजीर नहीं बनाया जा सकता है। और, in the documentation for the find_by_sql
method, हमें अतिरिक्त निराशा मिलती है ...
This should be a last resort because using, for example, MySQL specific terms will lock you to using that particular database engine or require you to change your call if you switch engines.
एक रेल-y रास्ता
वास्तव में, क्या एसक्यूएल ऊपर कर रहा है? यह उन नामों की एक सूची प्राप्त कर रहा है जो एक से अधिक बार प्रकट होते हैं। फिर, यह मूल तालिका के खिलाफ उस सूची से मेल खाता है। तो, चलो बस रेल का उपयोग कर ऐसा करते हैं।
titles_with_multiple = Movie.group(:title).having("count(title) > 1").count.keys
Movie.where(title: titles_with_multiple)
हम .keys
कहते हैं क्योंकि पहली क्वेरी एक हैश देता है। चाबियाँ हमारे खिताब हैं। where()
विधि एक सरणी ले सकती है, और हमने इसे शीर्षकों की एक सरणी सौंपी है। विजेता।
आप तर्क दे सकते हैं कि रूबी की एक पंक्ति दो से अधिक सुरुचिपूर्ण है। और यदि रूबी की उस पंक्ति में उसके भीतर एम्बेडेड एसक्यूएल की एक अजीब स्ट्रिंग है, तो वास्तव में यह कितना सुरुचिपूर्ण है?
आशा है कि इससे मदद मिलती है!
कमाल का जवाब, सुपर सूचनात्मक! सरणी के साथ बहुत अच्छी चाल। कहीं(), मैं प्रत्येक लूप को एक गुंजाइश करता। – Ashbury
खुशी है कि मैं मदद कर सकता हूं :) :) –