Ruby on rails Rails和SQL上的相同查询返回不同的结果
我需要帮助将此SQL转换为ActiveRecord查询Ruby on rails Rails和SQL上的相同查询返回不同的结果,ruby-on-rails,ruby,postgresql,ruby-on-rails-4,activerecord,Ruby On Rails,Ruby,Postgresql,Ruby On Rails 4,Activerecord,我需要帮助将此SQL转换为ActiveRecord查询 SELECT MAX(total_sales.start_date) AS maximum_start_date, customers.external_id, product_categories.external_id AS product_category_id FROM total_sales INNER JOIN customers ON customers.id = total_sales.custome
SELECT
MAX(total_sales.start_date) AS maximum_start_date,
customers.external_id, product_categories.external_id AS product_category_id
FROM
total_sales
INNER JOIN
customers
ON
customers.id = total_sales.customer_id
LEFT JOIN
product_categories
ON
product_categories.id = total_sales.product_category_id
WHERE
(customers.organization_id = 1)
GROUP BY
customers.external_id,
product_categories.external_id
我试过了
TotalSales.joins(:customer).includes(:product_category).
where("customers.organization_id = ?", 1).
group("customers.external_id, product_categories.external_id").
maximum(:start_date)
它几乎生成了我想要的查询。这就是它产生的结果:
SELECT
MAX("total_sales"."start_date") AS maximum_start_date,
customers.external_id, product_categories.external_id AS customers_external_id_product_categories_external_id
FROM
"total_sales"
INNER JOIN "customers" ON
"customers"."id" = "total_sales"."customer_id"
LEFT OUTER JOIN "product_categories" ON
"product_categories"."id" = "total_sales"."product_category_id"
WHERE
(customers.organization_id = 1)
GROUP BY
customers.external_id, product_categories.external_id
但这在轨道上得到了回报:
=> {"DIA"=>Wed, 01 Jan 2014, "MES"=>Wed, 01 Jan 2014, nil=>Wed, 01 Jan 2014}
如果我在DB控制台上运行该查询,它将返回
"2014-01-01";"CLIENTE.1";"DIA"
"2014-01-01";"CLIENTE.1";"MES"
"2014-01-01";"CLIENTE.1";""
"2014-01-01";"CLIENTE.10";"DIA"
"2014-01-01";"CLIENTE.10";"MES"
"2014-01-01";"CLIENTE.10";""
"2014-01-01";"CLIENTE.100";"DIA"
"2014-01-01";"CLIENTE.100";"MES"
...
这就是我想要的。在DB控制台上它可以工作,但在Rails上它不能:(这似乎是Rails中的一个bug。如果您使用
组更改您的线路,则从:
group("customers.external_id, product_categories.external_id").
致:
这很有效。NB!您应该使用逗号分隔的两个字符串。
必须是在Rails呈现SQL结果时,如果组位于一个字符串中,则认为该组只是一个字段,尽管它构建了正确的SQL查询
您将得到以下结果:
=> {["CLIENTE.1", "DIA"]=>Wed, 01 Jan 2014, ["CLIENTE.1", "MES"]=>Wed, 01 Jan 2014,
["CLIENTE.1", nil]=>Wed, 01 Jan 2014, ["CLIENTE.10", "DIA"]=>Wed, 01 Jan 2014,
["CLIENTE.10", "MES"]=>Wed, 01 Jan 2014, ["CLIENTE.10", nil]=>Wed, 01 Jan 2014, ...}
我想你知道如何使用它
有一点提示,请使用Arel
避免使用“硬编码”表名,您可以使用以下方法:
cust = Customer.arel_table
prod = ProductCategory.arel_table
TotalSales.joins(:customer).includes(:product_category).
where(cust[:organization_id].eq(1)).
group(cust[:external_id], prod[:external_id]).
maximum(:start_date)
包含!=左连接
如果希望查询以某种方式依赖于其他表
,则不应使用包含(其他表)
,因为包含
具有不同的语义
对于includes,您只需说ActiveRecord您打算很快从othertable获取对象,因此它应该为此进行优化。但它是面向对象的。在您的示例中,您可以获得TotalSales
对象
连接是一种关系数据库,表的列可以混合在一起。在对象世界中,我们通常不做这种事情。这就是为什么这经常变得困难的原因
如果你需要左连接,你需要告诉rails,根据rails指南,你确实需要使用SQL片段
TotalSales.joins('LEFT OUTER JOIN product_categories ON product_categories.id = total_sales.product_category_id')
...
另见我对这个问题的回答:
下面是一个工作查询的示例:。这在Rails上不起作用。.我猜是外部左连接vs左连接生成了该行为。查看:另请查看:一种方法可能是在获取记录后删除where和筛选,具体取决于记录集大小,使用或使用我们的外部查询生成所需的oDB控制台上的utput。问题似乎是AR如何在哈希上转换它。我相信这与两个group by列具有相同的名称有关。。
TotalSales.joins('LEFT OUTER JOIN product_categories ON product_categories.id = total_sales.product_category_id')
...