Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails和SQL上的相同查询返回不同的结果_Ruby On Rails_Ruby_Postgresql_Ruby On Rails 4_Activerecord - Fatal编程技术网

Ruby on rails Rails和SQL上的相同查询返回不同的结果

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

我需要帮助将此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.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')
...