mysql - 多个表(一个是子查询)连接

标签 mysql sql select join one-to-many

我(又)有这个表:

User:
id | name
-------------
1  | 'John'
2  | 'Peter'
3  | 'Luke'

Accounts:
id | userid | amount | date
--------------------------
1  | 1      | 1000   | '2012-01-26'
2  | 1      | 2000   | '2011-12-25'
3  | 1      | 1000   | '2012-01-25'
4  | 2      | 1500   | '2012-01-15'
5  | 3      | 2500   | '2011-11-30'

我需要收集数据,所以我同时有一个包含用户的结果集、每个用户的账户数、每个用户的账户金额总和,以及每个用户的帐户,但只有那些日期只有当年......

像这样:

Some-query:
UserName | CountAccts | SumAccts | CountAcctsThisYear
-----------------------------------------------------
'John'   | 3          | 4000     | 2
'Peter'  | 1          | 1500     | 1
'Luke'   | 1          | 2500     | 0

我设法通过此查询获得前 3 列:

SELECT u.name as Username,
       COUNT(a.id) as CountAccts,
       SUM(a.amount) as SumAccts
FROM   User u
LEFT JOIN Accounts a ON u.id = a.userid
GROUP BY u.id;

另外,我可以用另一个得到第一列和最后一列:

SELECT u.name as Username,
       COUNT(acctsthisyear.id) as CountAcctsThisYear
FROM   User u
LEFT JOIN (SELECT a.id
             FROM Accounts a
            WHERE DATE_FORMAT(a.date,'%Y') = DATE_FORMAT(CURDATE(),'%Y')
          ) AS acctsthisyear ON u.id = acctsthisyear.userid
GROUP BY u.id;

但是,这就是问题所在,我无法以这种方式使用这两个查询来获得我期望的最终结果...

我有... - 尝试左连接 Accounts 表和 acctsthisyear 子查询与 User 表(按 us.id 字段分组),但我得到的是这样的:

UserName | CountAccts | SumAccts | CountAcctsThisYear
-----------------------------------------------------
'John'   | 6          | 6000     | 6
'Peter'  | 1          | 1500     | 1
'Luke'   | 0          | 0        | 0

(记不住所有的细节,但事实是,例如,CountAcctsThisyear 中“John”的 2 个结果在结果中也重复了,并且所有结果都成倍增加了......)

  • 尝试将每个查询作为子查询: 选择 * 来自 (首先使用 u.id 查询作为 ufid 也被选中)AS 首先, (也选择了 u.id 作为 usid 的第二个查询)AS second GROUP BY ufid, usid

得到了这样的东西:

UserName | CountAccts | SumAccts | CountAcctsThisYear
-----------------------------------------------------
'John'   | 3          | 4000     | 2
'Peter'  | 1          | 1500     | 2
'Luke'   | 1          | 2500     | 2
'John'   | 3          | 4000     | 1
'Peter'  | 1          | 1500     | 1
'Luke'   | 1          | 2500     | 1
'John'   | 3          | 4000     | 0
'Peter'  | 1          | 1500     | 0
'Luke'   | 1          | 2500     | 0

(如果我按元素反转分组,我得到的都是相同的,但按不同的顺序分组......)

任何方式......就是这样......关于什么是实现我正在寻找的正确方法的任何想法?我真的很沮丧,因为我真的不是 SQL 专家,特别是 Joins :-/

最佳答案

试试这个:

SELECT u.`Name` as UserName,
       Count(*) as CountAccts,
       SUM(a.`amount`) as SumAccts,
       COALESCE(iTable.CountAcctsThisYear, 0) as CountAcctsThisYear
FROM    `User` u INNER JOIN `Accounts` a
                    ON u.`ID` = a`.`ID`
               LEFT JOIN
                   (SELECT `ID`, Count(*) as CountAcctsThisYear
                    FROM `Accounts`
                    WHERE DATE_FORMAT(`date`,'%Y') = DATE_FORMAT(CURDATE(),'%Y')
                    GROUP BY `ID`) as iTable
                ON `User`.`ID` = iTable.`ID`
GROUP BY `User`.`Name`

关于mysql - 多个表(一个是子查询)连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9029154/

相关文章:

Html 选择选项下划线

mysql - 如何从数据库中解析时间

MySQL Where OR 查询结果一个别名

javascript - 复选框和选择选项更新总计值

mysql - 对左连接组进行计数,排除结果数据中的零

sql - MS Outlook 使用 JAVA 工作

MySQL SELECT WHERE CASE

PHP SQL 搜索系统

mysql - 使用复合主键作为外键

sql - 用于多合一动态查询的 PL/pgSQL