SQL如何实现D'Hondt方法分配席位给选票?
How to implement the D'Hondt method to allocate seats to votes in SQL?
我有一个简单的 SQL(PostgreSQL 或 MySQL)table,其中行代表政党,而列代表他们在选举中获得的票数.我想使用 D'Hondt method.
为每一方(即新列)分配席位数 (n)
我应该编写什么过程(或函数)来做到这一点?
更新:假设要分配 4 个席位的所需输出示例:
votes allocated_seats
party1 47000 2
party2 16000 1
party3 15900 1
座位是这样分配的(D'Hondt 方法):
为每一方计算 V/(s+1)
其中 V:该党的票数
s: 已经分配给党的席位
价值最高的一方获得一个席位,这个过程重新开始,直到分配完所有席位。
所以在上面的例子中:
座位 1:
party1 47000/(0+1)=47000
party2 16000/(0+1)=16000
party3 15900/(0+1)=15900
party1 获得席位
座位 2:
party1 47000/(1+1)=23500
party2 16000/(0+1)=16000
party3 15900/(0+1)=15900
party1 获得席位
座位 3:
party1 47000/(2+1)=15666
party2 16000/(0+1)=16000
party3 15900/(0+1)=15900
party2获得席位
座位 4:
party1 47000/(2+1)=15666
party2 16000/(1+1)=8000
party3 15900/(0+1)=15900
party3获得席位
在 PostgreSQL 中,你不需要一个函数,一个简单的 update
就可以做到:
update dhont
set seats = coalesce(calculated.seats, 0)
from dhont as parties
left join (
select party, count(*) as seats
from (
select party
from dhont
cross join generate_series(1, :seat_count) as divisor
order by cast(votes as decimal) / divisor desc
limit :seat_count
) as seat_labels
group by party
) as calculated on parties.party = calculated.party
where parties.party = dhont.party
注意:这些是示例数据。对于实际的 join
条件,请使用您的 table 的主键(或至少是唯一键),而不仅仅是派对的名称。
理论上,同样可以在MySQL too, but with an ugly workaround中工作。
我有一个简单的 SQL(PostgreSQL 或 MySQL)table,其中行代表政党,而列代表他们在选举中获得的票数.我想使用 D'Hondt method.
为每一方(即新列)分配席位数 (n)我应该编写什么过程(或函数)来做到这一点?
更新:假设要分配 4 个席位的所需输出示例:
votes allocated_seats
party1 47000 2
party2 16000 1
party3 15900 1
座位是这样分配的(D'Hondt 方法):
为每一方计算 V/(s+1)
其中 V:该党的票数
s: 已经分配给党的席位
价值最高的一方获得一个席位,这个过程重新开始,直到分配完所有席位。
所以在上面的例子中:
座位 1:
party1 47000/(0+1)=47000
party2 16000/(0+1)=16000
party3 15900/(0+1)=15900
party1 获得席位
座位 2:
party1 47000/(1+1)=23500
party2 16000/(0+1)=16000
party3 15900/(0+1)=15900
party1 获得席位
座位 3:
party1 47000/(2+1)=15666
party2 16000/(0+1)=16000
party3 15900/(0+1)=15900
party2获得席位
座位 4:
party1 47000/(2+1)=15666
party2 16000/(1+1)=8000
party3 15900/(0+1)=15900
party3获得席位
在 PostgreSQL 中,你不需要一个函数,一个简单的 update
就可以做到:
update dhont
set seats = coalesce(calculated.seats, 0)
from dhont as parties
left join (
select party, count(*) as seats
from (
select party
from dhont
cross join generate_series(1, :seat_count) as divisor
order by cast(votes as decimal) / divisor desc
limit :seat_count
) as seat_labels
group by party
) as calculated on parties.party = calculated.party
where parties.party = dhont.party
注意:这些是示例数据。对于实际的 join
条件,请使用您的 table 的主键(或至少是唯一键),而不仅仅是派对的名称。
理论上,同样可以在MySQL too, but with an ugly workaround中工作。