从原始 sql 查询返回具有多个键/值对的哈希



我正在构建一个使用原始SQL查询数据库的Ruby on rails应用程序。

为了简单起见,我在表1中有以下记录:

<date:"2020-06-09 23:10:00", pid: 1, price: 5, tax: 0.65, shipping: 10>
<date:"2020-06-09 13:00:00", pid: 1, price: 10, tax: 1.3, shipping: 12>
<date:"2020-06-10 10:00:00", pid: 2, price: 20, tax: 2.6, shipping: 11>
<date:"2020-06-10 11:00:00", pid: 3, price: 5, tax: 0.65, shipping: 13>

我的查询应该返回一个哈希,其中每个键代表一天,值将是唯一pid的计数和其余值的总和。因此,在这种情况下,响应将是:

{
2020-06-09: {
pid_count: 1,
price: 15,
tax: 1.95,
shipping: 22
},
2020-06-10: {
pid_count: 2,
price: 25,
tax: 3.25,
shipping: 24
}
}

我的查询是:

query = <<-SQL
SELECT TO_CHAR(TO_TIMESTAMP(table1.date), 'YYYY-MM-DD'), COUNT(DISTINCT table1.pid) as pid_count,
sum(table1.price) as price, sum(table1.tax) as tax, sum(table1.shipping) as shipping from table1
group by TO_CHAR(TO_TIMESTAMP(table1.date), 'YYYY-MM-DD')
SQL
results = ActiveRecord::Base.connection.execute(query).values

计算是正确的,但问题是这没有将它们正确分组到哈希中。在results上调用 .to_h 会产生错误ArgumentError (wrong array length at 0 (expected 2, was 5))

无法调用to_h的原因是该方法需要结构:

[
[key, value],
[key, value],
# ...
]

而你有以下结构:

[
[value_1, value_2, value_3, value_4, value_5],
[value_1, value_2, value_3, value_4, value_5],
# ...
]

要正确地将其转换为您想要的结构,您必须通过提供一个块来告诉to_h如何做到这一点。

column_names = %i[pid_count price tax shipping]
hash = results.to_h { |date, *values| [date, column_names.zip(values).to_h] }

这会告诉to_h调用使用 date 作为键,然后将列名与其他值一起压缩,并将它们转换为哈希并将它们用作值。

以上可能会解决问题,但在大多数情况下,无需开始使用execute。假设table1有一个模型,我建议使用模型方法,例如groupselect/pluck。这些可以提供给SQL或Arel用于更复杂的查询。

最新更新