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

标签 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.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

但是这会在 Rails 上返回:

=> {"DIA"=>Wed, 01 Jan 2014, "MES"=>Wed, 01 Jan 2014, nil=>Wed, 01 Jan 2014}

如果我在数据库控制台上运行该查询,它会返回

"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"
...

这就是我想要的。在数据库控制台上它可以工作,但在 Rails 上它不能。 :(

最佳答案

这似乎是 Rails 中的一个错误。如果您使用 group 更改您的行:

group("customers.external_id, product_categories.external_id").

到:

group("customers.external_id", "product_categories.external_id").

它有效。 <强>注意!你应该使用两个用逗号分隔的字符串。

一定是当 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)

关于ruby-on-rails - Rails 和 SQL 上的相同查询返回不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30381810/

相关文章:

css - 如何制作 Bootstrap 按钮,点击重定向到特定页面

ruby-on-rails - 如何一起静音对 Rails Controller 操作的调用

postgresql - 使用 pglogical 复制插入是否需要主键?

sql - 如何在 postgresql 动态 SQL 中引用变量?

ruby-on-rails - Rails,如何提交带有文本链接的表单?

ruby-on-rails - 多个字段的唯一索引......但不是你想的那样

ruby-on-rails - Rails 服务器未加载页面

ruby - 如果代码块评估为 false,则跳过 enumerable#map 上的值

ruby-on-rails - Rails - 在模块上包含 Elasticsearch ?

python - txpostgres 存储过程返回游标