SUM(DISTINCT)基于其他列

Dav*_*vid 17 mysql math sum distinct

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

+------+-------+------------+------------+
| id   | rate  | first_name | last_name  |
+------+-------+------------+------------+
Run Code Online (Sandbox Code Playgroud)

我需要做的是获取SUM费率列,但每个名称只需一次.例如,我有三行名为John Doe,每行的速率为8.我需要SUM那些行为8而不是24,因此它为每组名称计算一次.

SUM(DISTINCT last_name, first_name)当然,这不会起作用,因为我试图总结费率列,而不是名称.我知道在计算单个记录时,我可以使用COUNT(DISTINCT last_name, first_name),这就是我想要获得的行为类型SUM.

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

提前致谢!

Gon*_*o.- 10

select sum (rate)
from yourTable
group by first_name, last_name
Run Code Online (Sandbox Code Playgroud)

编辑

如果你想获得那些小" sums"的所有总和,你将获得所有表格的总和..

Select sum(rate) from YourTable
Run Code Online (Sandbox Code Playgroud)

但是,如果由于某种原因是不同的(where例如,如果您使用a ),并且您需要上述选择的总和,那就行了.

select sum(SumGrouped) from 
(    select sum (rate) as 'SumGrouped'
    from yourTable
    group by first_name, last_name) T1
Run Code Online (Sandbox Code Playgroud)

  • 我找到了我的解决方案:“SELECT SUM(rate) FROM (SELECT * FROM reports GROUP BY last_name,first_name) T1”感谢您的帮助,它确实让我朝着正确的方向前进。 (2认同)

小智 6

大卫说他找到了答案:

SELECT SUM(rate) FROM (SELECT * FROM records GROUP BY last_name, first_name) T1
Run Code Online (Sandbox Code Playgroud)

但是当你GROUP BY在内部查询中执行时,我认为你必须在你的内部使用聚合函数SELECT.所以,我认为答案更像是:

SELECT SUM(rate) FROM (SELECT MAX(rate) AS rate FROM records GROUP BY last_name, first_name) T1
Run Code Online (Sandbox Code Playgroud)

MAX()选择只为"last_name,first_name"组合选择一个"rate"但是MIN()应该工作相同,假设"last_name,first_name"总是将我们引导到相同的"rate",即使它在表中多次出现也是如此.这似乎是大卫最初的假设 - 对于一个独特的名称,我们只想获得一次,因为我们知道它将是相同的.


Pau*_*aul 5

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

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

CONV(SUBSTRING(MD5(CONCAT(first_name,last_name)), 1, 8), 16, 10)
Run Code Online (Sandbox Code Playgroud)

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

FORMAT(rate + CONV(SUBSTRING(MD5(CONCAT(first_name,last_name)), 1, 8), 16, 10)/1000000000000000, 16)
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 是的,我做到了。人们仍在寻找这个问题的答案(就像我昨天所做的那样),也许他们会很高兴看到不同的方法。 (5认同)