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

时间:2012-01-27 04:58:52

标签: 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个结果,在结果中也得到重复,并且所有细节都成倍增加......)

  • 尝试将每个查询作为子查询: SELECT * FROM (首先使用u.id进行查询,因为ufid也被选中)AS首先, (使用u.id作为usid的第二个查询也被选中)AS第二个 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

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

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

4 个答案:

答案 0 :(得分:2)

试试这个:

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`

答案 1 :(得分:1)

SELECT u.name as Username,
       COUNT(a.id) as CountAccts,
       SUM(a.amount) as SumAccts,
       SUM( CASE WHEN YEAR(a.date) = YEAR(CURDATE()) THEN 1 ELSE 0 END ) 
           as CountAcctsThisYear
FROM   User u
LEFT JOIN Accounts a ON u.id = a.userid
GROUP BY u.id;

答案 2 :(得分:1)

SELECT u.name as Username,
       COUNT(a.userid) as CountAccts,
       SUM(a.amount) as SumAccts,
       SUM( CASE WHEN YEAR(a.date) = YEAR(CURDATE()) THEN 1 ELSE 0 END ) 
           as CountAcctsThisYear
FROM Accounts a 
INNER JOIN  User u ON u.id = a.userid
GROUP BY a.userid;

答案 3 :(得分:0)

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

尝试一次!!!