开发者

SQL:Getting count from many tables for a user record in USER table.Whats the best approach?

I have 4 SQL server(2008 version) tables

1) USER- to store user information (Fields : UserId,UserName)
2) FILES - to store files uploaded by user (FileId,FileName,UserId)
3) PHOTOS -to store files uploaded by user (PhotoId,PhotoName,UserId)
4) GROUPS= to store groups created by user ( GroupId,GroupName,UserId)

Now I want to get a USER record with id=5 along with Total number of Files uploaded by userid 5,Total Photos uploaded by user id 5,Total groups created by userid 5.Can i get all these with a single query ? OR should i write a SELECT COUNT of each table with USER ID=5 in the where clause ( 3 queries.. ?)

I can write an inner join with USER and FILES and do the count to get the number of files uploaded by a purticular user.But how to add the number of photos and number of groups to the result ?

What is the best approach to do this ?

Sample Data

USER

USERID     USERNAME
------     ---------
1          Shyju
2          OMG
3          Gus

FILES

FILEID      FILENAME    USERID
------      --------    ------
101         Sample1     1
102         Secondone   1
103         NewOne      2
104         BetterOne   3
105         Ocean       3
106         Sea         3

GROUPS

GROUPID   GROUPNAME   USERID
-------   ---------   ------
 51       Group-A     1
 52       Group-B     2
 53       Group-C     2
 54       Group-D     2
 55       Group-开发者_开发知识库E     3
 56       Group-F     3

The Result i am looking for is

For User ID=1

 USERID  USERNAME  FILECOUNT  GROUPCOUNT
 ------  --------  ---------  ----------
  1      Shyju     2          1

For UserId=2

 USERID  USERNAME  FILECOUNT  GROUPCOUNT
 ------  --------  ---------  ----------
  2      OMG        1          3


Use:

   SELECT u.userid,
          u.username,
          COALESCE(f.numFiles, 0) AS numFiles,
          COALESCE(p.numPhotos, 0) AS numFiles,
          COALESCE(g.numGroups, 0) AS numGroups
     FROM [USER] u
LEFT JOIN (SELECT t.userid,
                  COUNT(*) AS numFiles
             FROM [FILES] t
         GROUP BY t.userid)f ON f.userid = u.userid
LEFT JOIN (SELECT t.userid,
                  COUNT(*) AS numPhotos
             FROM [PHOTOS] t
         GROUP BY t.userid) p ON p.userid = u.userid
LEFT JOIN (SELECT t.userid,
                  COUNT(*) AS numGroups
             FROM [GROUPS] t
         GROUP BY t.userid) g ON g.userid = u.userid
    WHERE u.userid = 2

You have to use OUTER joins for this to be in one query; INNER joins for all the tables would require that the user have at least one record in FILES, PHOTOS and GROUPS table to be in the resultset. An OUTER join means that users with records in at least one of the tables (FILES, PHOTOS or GROUPS) will be returned.

But JOINs also risk inflating the resultset, which is the issue that occurred in the previous version of my answer. By changing the query to use derived tables/inline views for the FILES, GROUPS and PHOTOS counts, the problem is solved and there's no need for a GROUP BY outside of the derived tables/inline views.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜