为什么find_by_sql不能与PostgreSQL一起使用?

时间:2013-06-19 05:23:17

标签: ruby-on-rails ruby postgresql find-by-sql

我有一个PostgreSQL查询,它按月汇总值,从日期中提取月份值:

SELECT vendors.name AS vendor, 
SUM(purchases.invoice_total) AS invoice_total, 
EXTRACT(MONTH FROM purchases.date) AS date 
FROM vendors, purchases 
WHERE purchases.vendor_id = vendors.id 
AND purchases.store_id = ? 
AND purchases.purchase_department_id = ? 
AND (purchases.date BETWEEN ? AND ?) 
GROUP BY vendor, EXTRACT(MONTH FROM purchases.date) 
ORDER BY vendor, date;

在DB控制台中直接执行查询后,我得到这样的结果:

+------------------------------------+---------------+------+
| vendor                             | invoice_total | date |
+------------------------------------+---------------+------+
| Store 1                            |        448.56 |    1 |
| Store 1                            |        263.44 |    2 |
| Store 1                            |        939.47 |    3 |

使用Rails'find_by_sql函数时会出现问题。正确返回vendorinvoice_total值,但日期值返回为nil。

#<Purchase date: nil, invoice_total: #<BigDecimal:85c75c8,'0.26344E3',18(18)>>

这是我的电话。我甚至尝试过使用硬编码值而没有任何东西,但它就像Extract函数不会在Rails中执行:

<% @purchasesSQL = Purchase.find_by_sql(["SELECT vendors.name AS vendor, SUM(purchases.invoice_total) AS invoice_total, 
    EXTRACT(MONTH FROM purchases.date) AS date 
    FROM vendors, purchases 
    WHERE purchases.vendor_id = vendors.id 
    AND purchases.store_id = ? 
    AND purchases.purchase_department_id = ? 
    AND (purchases.date BETWEEN ? AND ?) 
    GROUP BY vendor, EXTRACT(MONTH FROM purchases.date) 
    ORDER BY vendor, date;", @store.id, purchase_department.id, @start, @end])
%>

我已经做了一些调试,我传递的值不是零也不是错误。

1 个答案:

答案 0 :(得分:2)

你说你的date模型表中有一个名为Purchase的列(对于列BTW而言,这是一个可怕的名称,使用列名的类型名称只会导致痛苦和痛苦)。大概您的date列是datetimestamp。在Purchase.find_by_sql中,您有:

EXTRACT(MONTH FROM purchases.date) AS date 

Purchase.find_by_sql将尝试创建Purchase个实例。因此,您为Purchase提供了一个简单的号码并将其称为datePurchase可能会注意到它有一个date列,并尝试将您的简单号码解析为完整日期或时间戳。一个简单的数字不能以任何有意义的方式解析为日期或时间戳,因此它们可能都被转换为nil

这里有两件事要做:

  1. date列重命名为其他内容,与任何关键字都不冲突。
  2. 为了解决您的直接问题,请为您的月份编号使用不同的别名:

    EXTRACT(MONTH FROM purchases.date) AS month_number
    

    这应该会为返回的month_number对象提供Purchase方法。