1

まず、私はmysqlをずっと使用していて、現在postgresqlにアップグレードしています。SQL構文ははるかに厳密で、一部の動作が異なるため、私の質問です。

私は次のようなテーブルのpostgresqlクエリで行をマージする方法を探していました

id      | name        |   amount
0       | foo         | 12
1       | bar         | 10
2       | bar         | 13
3       | foo         | 20

取得します

name        |   amount
foo         | 32
bar         | 23

私が見つけた最も近いものは、重複するレコードを同じテーブルとテーブルフィールドを持つ1つのレコードにマージすることです

'name'の重複を返すSQL:

 scope :tallied, lambda { group(:name, :amount).select("charges.name AS name,
                              SUM(charges.amount) AS amount,
                              COUNT(*) AS tally").order("name, amount desc") }


必要なのは

 scope :tallied, lambda { group(:name, :amount).select("DISTINCT ON(charges.name) charges.name AS name,
                              SUM(charges.amount) AS amount,
                              COUNT(*) AS tally").order("name, amount desc") }

ただし、指定された名前の最初の行を返すのではなく、指定された名前(追加された量)を持つすべての行のマッシュを返す必要があります

mysqlでは.group(:name)、selectへの追加(初期グループは不要)は期待どおりに機能します。

これは、簡単なはずの日常的な作業のようです。これを行う簡単な方法は何でしょうか?正しい道を教えてください。

PS私はここで学ぼうとしています(他の人もそうです)。SQLを顔に投げかけるだけでなく、説明してください。

4

1 に答える 1

1

RoRがバックグラウンドで何をしているのかわかりませんがgroup(:name, :amount)、名前と金額でグループ化するクエリが実行されると思います。あなたが探しているものはgroup by name

select name, sum(amount) as amount, count(*) as tally
from charges
group by name

句に追加amountすると、クエリはまさにそれを実行します。つまり、名前ごとに各金額が表示される回数を返し、その回数にその金額を返します。group bycount(*)sum()

于 2011-05-31T09:35:21.750 に答える