我有一张表:
+--------+-----------+-------+-----------+
|house_no|house_alpha|flat_no|street_name|
+--------+-----------+-------+-----------+
| 1| | |James St |
| 1| | |James St |
| 1| | |James St |
| 2| A| |James St |
| 2| B| |James St |
| 3| A| |James St |
| 4| | 416|James St |
| 4| | 416|James St |
+--------+-----------+-------+-----------+
我正在尝试计算此表中不同地址的数量。 这将返回不同的地址:
Address.all(:select => 'street_name, flat_no, house_no, house_alpha',
:group => 'street_name, flat_no, house_no, house_alpha').length
但我想在SQL端做到这一点。并试图结合计数和小组不喜欢我。我显然做错了什么。
(数据库是postgres,rails是2.x)。
答案 0 :(得分:6)
对于带有Arel的rails 3,您可以执行以下操作:
Address.group(:street_name, :flat_no, :house_no, :house_alpha).having("count(*) > 0").count.size
答案 1 :(得分:2)
我不确定是否有一种漂亮的Rails方法可以跨分组列进行计数。在SQL中有很多奇怪的方法可以做到这一点,但这种方式很容易理解。
Address.find(:all,
:select => "count(*) as addr_count",
:having => "addr_count > 0",
:group => 'street_name, flat_no, house_no, house_alpha').size
这将运行以下SQL查询。
SELECT count(*) as addr_count FROM "addresses" GROUP BY street_name, flat_no, house_no, house_alpha HAVING addr_count > 0
编辑:请阅读Postgres
从下面的评论中,以下是在Postgres上执行上述操作的方法。
Address.find(:all,
:select => "count(*)",
:having => "count(*) > 0",
:group => 'street_name, flat_no, house_no, house_alpha').size
这将生成以下查询。
SELECT count(*) FROM "addresses" GROUP BY street_name, flat_no, house_no, house_alpha HAVING count(*) > 0
答案 2 :(得分:1)
在 Rails 2 中,我发现:group
选项不能正常运行(在我最新的情况下,它创建了一个只包含每组中第一条记录的数组)。作为替代方案,您可以将数据库搜索与EnumerableArray#group_by
结合使用,如下所示:
addresses = Address.find(:all,
:select => "count(*) as addr_count",
:having => "addr_count > 0"),
grouped_addrs = addresses.group_by{|a| [a.street_name, a.flat_no, a.house_no, a.house_alpha] }