web-dev-qa-db-ja.com

他の列に基づくSUM(DISTINCT)

現在、次のようなテーブルがあります。

_+------+-------+------------+------------+
| id   | rate  | first_name | last_name  |
+------+-------+------------+------------+
_

私がする必要があるのは、rate列のSUMを取得することですが、名前ごとに1回だけです。たとえば、John Doeという名前の3つの行があり、それぞれのレートは8です。これらの行のSUMは24ではなく8である必要があるため、名前のグループごとに1回レートをカウントします。

名前ではなく、rate列を合計しようとしているため、SUM(DISTINCT last_name, first_name)はもちろん機能しません。個々のレコードを数えるときはCOUNT(DISTINCT last_name, first_name)を使用できます。これがSUMから取得しようとしている動作のタイプです。

名前ごとにSUM 1つのレートを取得するにはどうすればよいですか?

前もって感謝します!

18
David
select sum (rate)
from yourTable
group by first_name, last_name

編集

これらの小さな "sums"の合計を取得したい場合は、すべてのテーブルの合計を取得します。

Select sum(rate) from YourTable

しかし、何らかの理由で違いがあり(たとえば、whereを使用する場合)、上記の選択の合計が必要な場合は、実行してください。

select sum(SumGrouped) from 
(    select sum (rate) as 'SumGrouped'
    from yourTable
    group by first_name, last_name) T1
10
Gonzalo.-

デービッドは彼がそのように彼の答えを見つけたと言いました:

_SELECT SUM(rate) FROM (SELECT * FROM records GROUP BY last_name, first_name) T1
_

しかし、内部クエリで_GROUP BY_を実行する場合、SELECTで集計関数を使用する必要があると思います。だから、私は答えはもっと似ていると思います:

_SELECT SUM(rate) FROM (SELECT MAX(rate) AS rate FROM records GROUP BY last_name, first_name) T1
_

「last_name、first_name」の組み合わせに対して「レート」を1つだけ選択するためにMAX()を選択しましたが、MIN()も同じように機能するはずです。「last_name、first_name」は常にテーブルで複数回発生した場合でも同じ「レート」。これは、Davidの元々の仮定のようです-一意の名前の場合、同じになることがわかっているため、レートを一度だけ取得したいと考えています。

6
SELECT SUM(rate)
FROM [TABLE] 
GROUP BY first_name, last_name;
2
Vasil Nikolov
SELECT SUM(rate)
FROM [TABLE] 
GROUP BY CONCAT_WS(' ', first_name, last_name);
1
MetalFrog

集計関数のないgroup by句を使用すると、グループ化条件ごとに不確定な1つのレコードが返されるため、上記のコードサンプルを使用できます。詳細については http://dev.mysql.com/doc/refman/5.5/en/group-by-hidden-columns.html リンクを参照してください。

0
Manisha Mahawar

これを行うには、合計する値を区別します。これは可能ですが、非常に非常に醜いです。

まず、ハッシュを取得することで文字列を数値に変換できます。以下のSQLは、姓と名のMD5ハッシュを実行し、32桁の16進数を返します。 SUBSTRINGはこれらの最初の8つを取り、CONVはそれを10桁の数字に変換します(理論的にはこれは一意ではない可能性があります)。

CONV(SUBSTRING(MD5(CONCAT(first_name,last_name)), 1, 8), 16, 10)

次に、それを非常に大きな数で割り、レートに追加します。最終的には8.0000019351087950のようなレートになります。 MySQLが小数点以下を切り捨てないようにするには、FORMATを使用する必要があります。このレートは、姓名ごとに一意になります。

FORMAT(rate + CONV(SUBSTRING(MD5(CONCAT(first_name,last_name)), 1, 8), 16, 10)/1000000000000000, 16)

そして、その上でSUM DISTINCTを実行すると、8は1度しかカウントされません。次に、結果をFLOORして、余分な小数点以下を取り除く必要があります。

FLOOR(SUM(DISTINCT FORMAT(rate + CONV(SUBSTRING(MD5(CONCAT(first_name,last_name)), 1, 8), 16, 10)/1000000000000000, 16)))

複数のテーブルを結合してグループ化するはるかに複雑なクエリを実行しているときに、このアプローチを見つけました。かなり恐ろしいので使用するかどうかはまだわかりませんが、動作します。また、質問に答えた人に役立たせるには6年も遅すぎます。

0
Paul