22

我目前有一个看起来像这样的表:

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

我需要做的是获取SUMrate 列的,但每个名称只有一次。例如,我有三行姓名 John Doe,每行的比率为 8。我需要SUM这些行中的 8 行,而不是 24,因此它为每组名称计算一次比率。

SUM(DISTINCT last_name, first_name)当然,这是行不通的,因为我试图对比率列求和,而不是对名称求和。我知道在计算单个记录时,我可以使用COUNT(DISTINCT last_name, first_name),这就是我试图从中获得的行为类型SUM

我怎样才能SUM为每个名称只获得一个费率?

提前致谢!

4

8 回答 8

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

编辑

如果你想得到那些小“ sums”的所有总和,你将得到所有表的总和..

Select sum(rate) from YourTable

但是,如果由于某种原因有所不同(where例如,如果您使用 a )并且您需要对上面的选择进行总和,那就去做。

select sum(SumGrouped) from 
(    select sum (rate) as 'SumGrouped'
    from yourTable
    group by first_name, last_name) T1
于 2012-08-02T17:03:32.040 回答
7

David said he found his answer as such:

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

But when you do the GROUP BY in the inner query, I think you have to use aggregate functions in your SELECT. So, I think the answer is more like:

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

I picked MAX() to pick only one "rate" for a "last_name, first_name" combination but MIN() should work the same, assuming that the "last_name, first_name" always leads us to the same "rate" even when it happens multiple times in the table. This seems to be David's original assumption - that for a unique name we want to grab the rate only once because we know it will be the same.

于 2015-06-22T22:26:03.820 回答
6

您可以通过使要求和的值不同来做到这一点。这是可能的,但非常非常难看

首先,您可以通过哈希将字符串转换为数字。下面的 SQL 对名字和姓氏进行 MD5 哈希,返回 32 个十六进制数字。SUBSTRING 取其中的前 8 个,CONV 将其转换为 10 位数字(理论上这可能不是唯一的):

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

然后你将它除以一个非常大的数字并将其添加到费率中。你最终会得到一个像 8.0000019351087950 这样的费率。您必须使用 FORMAT 来避免 MySQL 截断小数位。这个比率现在对于每个名字和姓氏都是唯一的。

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

然后,如果您对其进行 SUM DISTINCT ,它只会计算 8 一次。然后你需要对结果进行 FLOOR 以去除多余的小数位:

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

我在做一个更复杂的查询时发现了这种方法,该查询连接并分组了几个表。我仍然不确定我是否会使用它,因为它非常可怕,但它确实有效。对于回答问题的人来说,这也太迟了 6 年。

于 2019-03-13T16:47:05.057 回答
2
SELECT SUM(rate)
FROM [TABLE] 
GROUP BY first_name, last_name;
于 2012-08-02T17:12:30.410 回答
1
SELECT SUM(rate)
FROM [TABLE] 
GROUP BY CONCAT_WS(' ', first_name, last_name);
于 2012-08-02T17:01:51.920 回答
1

最近,我遇到了一个类似的问题,但我已经有了一个用于不同目的的 GROUP BY 子句。这是一个例子:

SELECT r.name, SUM(r.rate), MIN(e.created_at)
FROM Rates r LEFT JOIN Events e ON r.id = e.rate_id
GROUP BY r.id

这里的问题是,由于 JOIN with EventSUM(r.rate)将汇总具有多个事件的条目的重复项。在我的情况下,查询要复杂得多,所以我想避免有额外的子查询。幸运的是,有一个优雅的解决方案:

SELECT r.name, SUM(r.rate) / GREATEST(COUNT(DISTINCT e.event_id), 1), MIN(e.created_at)
FROM Rates r LEFT JOIN Events e ON r.id = e.rate_id
GROUP BY r.id

GREATEST函数用于防止没有任何事件的条目被零除。如果您正在对整数求和,您可能还希望将总和转换为 INT

于 2022-01-21T17:26:26.040 回答
0

您可以使用上面提供的任何代码示例,因为没有任何聚合函数的 group by 子句将为每个分组条件返回一个不确定的记录。您可以参考http://dev.mysql.com/doc/refman/5.5/en/group-by-hidden-columns.html链接进行进一步阅读。

于 2012-08-02T17:46:31.917 回答
0

我发现这个线程正在寻找一种更好的方法来解决我的问题,但我仍然没有找到更好的方法:

SELECT SUM(rate) FROM (SELECT DISTINCT rate, first_name, last_name) Q
于 2021-04-30T07:12:18.103 回答