如何通过连接具有重复数据的2列来给出空间

时间:2014-10-29 17:57:15

标签: mysql sql

我有一个像这样的表结构

CREATE TABLE `test` (
  `id` int(11) NOT NULL,
  `userid` int(11) DEFAULT NULL,
  `loan` int(11) DEFAULT NULL,
  `name` varchar(90) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8


+----+--------+------+--------+
| id | userid | loan | name   |
+----+--------+------+--------+
|  1 |      1 |  100 | x |
|  2 |      1 |  200 | X|
|  3 |      2 | 2000 | y|
|  4 |      3 | 1000 | z|
|  5 |      1 |  500 | a|
|  6 |      2 |  700 | b|

正如您所见,用户ID正在重复。例如,用户ID 1有贷款100,200和500

我的要求是获取用户ID,贷款和名称,如果用户ID正在重复,那么贷款将是重复用户ID的总和,名称应该是空格 例如,在上表中,用户标识1重复,因此总和为(100 + 200 + 500 = 800) 类似地,对于用户ID 2,总和是2700 我想要的输出应该如下所示

+--------+-----------+----+
| userid | SUM(loan) |name|
+--------+-----------+----+
|      1 |       800 |    |
|      2 |      2700 |    |
|      3 |      1000 |z   |
+--------+-----------+

我可以使用userid和贷款,但我不知道如果用户ID重复,如何在名称字段中放置空格

我试过这个

SELECT userid,SUM(loan) FROM
testforsum
GROUP BY userid

我得到的输出就是这样

+--------+-----------+
| userid | SUM(loan) |
+--------+-----------+
|      1 |       800 |
|      2 |      2700 |
|      3 |      1000 |
+--------+-----------+

我尝试为它创建一个sqlfiddle,但我不知道为什么插入没有发生。你可以看到表here

2 个答案:

答案 0 :(得分:2)

SELECT userid, IF(COUNT(*) > 1, ' ', name) AS name, SUM(loan) 
FROM testforsum GROUP BY userid;

答案 1 :(得分:1)

select q.userid, q.s, 
       case when q.n > 1 then ' ' else q.name end
from
(SELECT userid, SUM(loan) s, count(loan) n, max(name) name
FROM testforsum GROUP BY userid) q;

一些解释:

(...) q是一个子查询,它计算每个userId贷款总额(忽略NULLS),贷款数量(忽略NULLS)。

max(name)这是一个“假的”聚合函数,我用它来获取每个userId的任何名称(它们对于每个userId都是相同的,所以我可以这样做)因为在ANSI SQL中这个查询是错误的:

SELECT userid, IF(COUNT(*) > 1, ' ', name) AS name, SUM(loan) 
FROM testforsum GROUP BY userid;

因为SELECT列表中的所有表达式都应该是聚合函数(对于多行返回单个值)或者来自GROUP BY子句的表达式。据我所知,MySQL允许你破坏这些规则,但我更愿意在可能的情况下遵循ANSI。

因此,子查询 q 会产生一个包含唯一userIds的表,其中包含名称+总和及其贷款数。

最后,父查询使用CASE过滤 q 子查询的结果。