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

梦想的初衷 提交于 2020-01-24 12:23:27

问题


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

回答1:


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.



来源:https://stackoverflow.com/questions/3835678/sqlgetting-count-from-many-tables-for-a-user-record-in-user-table-whats-the-bes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!