簡體   English   中英

Rails中的復雜查詢

[英]Complex query in Rails

我正在嘗試為VRP構建一個簡單的求解器Web應用程序。 我的問題是如何建立一個查詢,以返回每個客戶及其用戶名,經度,緯度和他的產品以及所有產品列產品最后庫存的數量?

數據庫圖: 數據庫方案 客戶與用戶的關系是一對一的(用戶是客戶的超類)

推銷員與用戶的關系是一對一的(用戶是推銷員的超類)

推銷員和客戶關系是一對多的(推銷員有很多客戶)

客戶與產品的關系是一對多的(一個客戶有很多產品)

產品和庫存關系是一對多的(需要記錄每個庫存變化)

歡迎任何更改數據庫方案的建議

實際上,您實際上不需要為每個模型構建查詢。

您可以從為客戶建立一個查詢開始: @customers = Customer.all然后通過不同模型之間存在的關系從那里訪問所需的任何數據。

即:

查詢客戶的用戶名,經度和緯度(以第一個客戶為例,但是您可以使用Customer.where(:user_id => some_number).find進行.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 = Customer.all並輸出結果,則結果如下所示:

@customers.each do |customer|
 customer.username
end

由於您的數據是以這種復雜的方式構造的,因此使用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

對於Rails部分,您可以使用類似以下內容的方法:

data = Users.select("id, longitude etc").
  joins(
    "INNER JOIN customers ON user_id = users.id etc "
)

SQL Fiddle鏈接

您可以在模型類中添加方法,並通過相關關系返回所需的一切。 瀏覽Rails文檔活動記錄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM