मैं VRP के लिए एक सरल सॉल्वर वेब एप्लिकेशन बनाने का प्रयास कर रहा हूं। मेरा सवाल यह है कि मैं एक क्वेरी कैसे बना सकता हूं जो प्रत्येक ग्राहक को उसके उपयोगकर्ता के उपयोगकर्ता नाम, देशांतर, अक्षांश और उसके उत्पादों के साथ सभी उत्पाद कॉलम और उत्पाद के अंतिम स्टॉक की मात्रा के साथ लौटाता है?
डेटाबेस का आरेख: ग्राहक और उपयोगकर्ता संबंध एक-से-एक है (उपयोगकर्ता ग्राहक का एक सुपरक्लास है)
सेल्समैन और यूजर का संबंध एक-से-एक है (उपयोगकर्ता सेल्समैन का सुपरक्लास है)
सेल्समैन और ग्राहक संबंध एक-से-अनेक होते हैं (एक सेल्समैन के कई ग्राहक होते हैं)
ग्राहक और उत्पाद संबंध एक-से-अनेक हैं (एक ग्राहक के पास कई उत्पाद हैं)
उत्पाद और स्टॉक संबंध एक से कई हैं (प्रत्येक स्टॉक परिवर्तन को रिकॉर्ड करने की आवश्यकता है)
डेटाबेस योजना को बदलने के किसी भी सुझाव का स्वागत है
3 जवाब
चूंकि आपका डेटा इतने जटिल तरीके से संरचित है, इसलिए ActiveRecord ऑब्जेक्ट्स के साथ सब कुछ पुनर्प्राप्त करने से बहुत तेज़ हो जाएगा (हाल ही में यह समस्या थी)।
आइए देखें कि हम एक साथ क्या पता लगा सकते हैं।
चूंकि आपने MySQL प्रश्न के लिए नमूना डेटा प्रदान नहीं किया है, इसलिए मैंने इसे अपने आप में भर दिया है, लेकिन डेटा में सुधार करने के लिए स्वतंत्र महसूस करें और हम एक बेहतर समाधान पर आ सकते हैं।
योजना
CREATE TABLE IF NOT EXISTS `users` (
`id` int(6) unsigned NOT NULL,
`username` varchar(200) NOT NULL,
`longitude` varchar(200) NOT NULL,
`latitude` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `customers` (
`id` int(6) unsigned NOT NULL,
`user_id` int(6) unsigned NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `products` (
`id` int(6) unsigned NOT NULL,
`customer_id` int(6) unsigned NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `stocks` (
`id` int(6) unsigned NOT NULL,
`product_id` int(6) unsigned NOT NULL,
`quantity` int(200) unsigned NOT NULL,
`updated_at` DATETIME,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `users` (`id`, `username`, `longitude`, `latitude`) VALUES
(1, 'username1', '11.12', '22.33'),
(2, 'username2', '11.12', '22.33'),
(3, 'username3', '11.12', '22.33');
INSERT INTO `customers` (`id`, `user_id`) VALUES
(9, 1),
(10, 2),
(11, 3);
INSERT INTO `products` (`id`, `customer_id`) VALUES
(33, 9),
(34, 10),
(35, 11);
INSERT INTO `stocks` (`id`, `product_id`, `quantity`, `updated_at`) VALUES
(1, 33, 12, '2017-07-17 13:24:01'),
(2, 34, 1, '2017-07-17 13:24:02'),
(3, 35, 99, '2017-07-17 13:24:03'),
(4, 36, 3, '2017-07-17 13:31:01');
जिज्ञासा
SELECT users.id, username, longitude, latitude, products.id as product_id, quantity from `users`
INNER JOIN customers ON user_id = users.id
INNER JOIN products ON customer_id = customers.id
INNER JOIN stocks ON product_id = products.id
ORDER BY stocks.updated_at DESC
परिणाम
id username longitude latitude product_id quantity
1 username1 11.12 22.33 33 12
2 username2 11.12 22.33 34 1
3 username3 11.12 22.33 35 99
रेल भाग के लिए आप कुछ इस तरह उपयोग कर सकते हैं:
data = Users.select("id, longitude etc").
joins(
"INNER JOIN customers ON user_id = users.id etc "
)
आपको वास्तव में प्रत्येक मॉडल के लिए एक क्वेरी बनाने की आवश्यकता नहीं है।
आप ग्राहकों के लिए एकल क्वेरी बनाकर शुरुआत कर सकते हैं: @customers = Customer.all
और वहां से विभिन्न मॉडलों के बीच मौजूद संबंधों के माध्यम से, आप जो भी डेटा चाहते हैं, उस तक पहुंच सकते हैं।
अर्थात।:
ग्राहक के उपयोगकर्ता नाम, देशांतर और अक्षांश की क्वेरी करना (उदाहरण के रूप में पहले ग्राहक का उपयोग किया गया था, लेकिन आप Customer.where(:user_id => some_number)
या .find
का उपयोग करके क्वेरी कर सकते हैं।
customer = Customer.all.first
customer.user.username
customer.user.longtitude
customer.user.latitude
नीचे दी गई क्वेरी पहले ग्राहक के पहले उत्पाद और उस उत्पाद के पहले स्टॉक को हथियाने के लिए काम करेगी। एक बार फिर आप विभिन्न तरीकों जैसे .find
और .where
का उपयोग सटीक उत्पाद और परिणामी स्टॉक को क्वेरी करने के लिए कर सकते हैं जिसकी आपको आवश्यकता है।
customer.products.first.stocks.first
यदि आप सभी ग्राहकों को पकड़ना चाहते हैं (@customers = Customer.all
के लिए एक आवृत्ति चर का उपयोग करना और प्रत्येक के माध्यम से लूप करना और परिणाम आउटपुट करना चाहते हैं, तो यह कुछ ऐसा दिखाई देगा:
@customers.each do |customer|
customer.username
end
आप मॉडल वर्ग के अंदर विधि जोड़ सकते हैं और प्रासंगिक संबंधों के साथ आपको जो कुछ भी चाहिए उसे वापस कर सकते हैं। रेल दस्तावेज़ीकरण सक्रिय रिकॉर्ड में एक नज़र डालें
संबंधित सवाल
नए सवाल
sql
संरचित क्वेरी भाषा (एसक्यूएल) डेटाबेस को क्वेरी करने के लिए एक भाषा है। प्रश्नों में कोड उदाहरण, तालिका संरचना, नमूना डेटा और DBMS कार्यान्वयन के लिए एक टैग (जैसे MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2, आदि) का उपयोग किया जाना चाहिए। यदि आपका प्रश्न केवल एक विशिष्ट DBMS (विशिष्ट एक्सटेंशन / सुविधाओं का उपयोग करता है) से संबंधित है, तो इसके बजाय उस DBMS के टैग का उपयोग करें। एसक्यूएल के साथ टैग किए गए सवालों के जवाब में आईएसओ / आईईसी मानक एसक्यूएल का उपयोग करना चाहिए।