2017-10-06 137 views
1

我想要获取用户在不同表中输入的记录数。 DB的模式是:根据加入从不同表中选择记录数

+-----------------------+ 
| Survey Master   | 
+----------------+------+ 
| Field   | Key | 
+----------------+------+ 
| id    | PK | 
| Username  |  | 
| FamilyMasterId | FK | 
+----------------+------+ 

+------------+------+ 
| Family Master  | 
+------------+------+ 
| Field  | Key | 
+------------+------+ 
| id   | PK | 
+------------+------+ 

+-----------------------+ 
| Family Detail   | 
+----------------+------+ 
| Field   | Key | 
+----------------+------+ 
| id    | PK | 
| FamilyMasterId | FK | 
+----------------+------+ 

+-----------------------+ 
| Travel Master   | 
+----------------+------+ 
| Field   | Key | 
+----------------+------+ 
| id    | PK | 
| FamilyDetailId | FK | 
+----------------+------+ 

+-----------------------+ 
| Travel Detail   | 
+----------------+------+ 
| Field   | Key | 
+----------------+------+ 
| id    | PK | 
| TravelMasterId | FK | 
+----------------+------+ 

我希望看到每个用户在每个表是这样创造的记录数:

    Username SurveyMaster FamilyMaster FamilyDetail TravelMaster TravelDetail 
    ---------- -------------- -------------- -------------- -------------- -------------- 
        User001 59    47    36    26    12    
        User002 88    76    64    42    25    
        User003 49    44    35    25    15    
        User004 77    69    55    45    37 
    

    查看以下链接后

  1. Find Records from Different Tables
  2. Select count(*) from multiple tables
  3. http://www.sqlines.com/mysql/how-to/join-different-tables-based-on-condition
  4. http://www.informit.com/articles/article.aspx?p=30875&seqNum=5
  5. SQL: Combine Select count(*) from multiple tables

我能写这个查询,但它给出了相同的记录中的所有列:

SELECT USERNAME, COUNT(USERNAME) SURVEYMASTER, COUNT(USERNAME) FAMILYMASTER, COUNT(USERNAME) FAMILYDETAIL, COUNT(USERNAME) TRAVELMASTER, COUNT(USERNAME) TRAVELDETAIL FROM 
((SELECT CREATEUSER USERNAME FROM SURVEYMASTER 
) 
UNION ALL 
(SELECT SM.CREATEUSER USERNAME FROM SURVEYMASTER SM 
INNER JOIN FAMILYMASTER FM ON FM.ID = SM.FAMILYMASTERID 
) 
UNION ALL 
(SELECT SM.CREATEUSER USERNAME FROM SURVEYMASTER SM 
INNER JOIN FAMILYMASTER FM ON FM.ID = SM.FAMILYMASTERID 
INNER JOIN FAMILYDETAIL FD ON FM.ID = FD.FAMILYMASTERID 
) 
UNION ALL 
(SELECT SM.CREATEUSER USERNAME FROM SURVEYMASTER SM 
INNER JOIN FAMILYMASTER FM ON FM.ID = SM.FAMILYMASTERID 
INNER JOIN FAMILYDETAIL FD ON FM.ID = FD.FAMILYMASTERID 
INNER JOIN TRAVELMASTER TM ON FD.ID = TM.FAMILYDETAILID 
) 
UNION ALL 
(SELECT SM.CREATEUSER USERNAME FROM SURVEYMASTER SM 
INNER JOIN FAMILYMASTER FM ON FM.ID = SM.FAMILYMASTERID 
INNER JOIN FAMILYDETAIL FD ON FM.ID = FD.FAMILYMASTERID 
INNER JOIN TRAVELMASTER TM ON FD.ID = TM.FAMILYDETAILID 
INNER JOIN TRAVELDETAIL TD ON TM.ID = TD.TRAVELMASTERID 
) 
) T 
GROUP BY USERNAME 
ORDER BY USERNAME 

编辑

这里是关系描述:

  1. FamilyMasterId是SurveyMaster和FamilyDetail 表中的外键。
  2. FamilyDetailId是TravelMaster表中的外键。
  3. TravelMasterId是TravelDetail表中的外键。
+0

如果性能是不是一个问题,你可以使用一个单独的子查询中获取每个计数。顺便说一句,表格之间的关系并不清楚。 – FLICKER

+0

'以获得用户在不同表中输入的记录的数量** **每个表中都需要USERID **例如created_by_userid –

+0

@Used_By_Already没有办法让我们可以通过所有表格之间的连接来计数 –

回答

1

这可能不是完美的解决方案,如果我们考虑性能,但它可以得到期望的结果

SELECT sm.Username , 
     COUNT(*) SurveyMaster , 
     COUNT(FamilyMasterId) FamilyMaster , 
     fd.FamilyDetail , 
     tm.TravelMaster , 
     td.TravelDetail 
FROM SurveyMaster sm 
     JOIN (SELECT Username , 
         COUNT(fd.id) FamilyDetail 
       FROM  SurveyMaster sm 
         JOIN FamilyMaster fm ON sm.FamilyMasterId = fm.Id 
         JOIN FamilyDetail fd ON fm.id = fd.FamilyMasterId 
       GROUP BY Username 
      ) fd ON sm.Username = fd.Username 
     JOIN (SELECT Username , 
         COUNT(tm.id) TravelMaster 
       FROM  SurveyMaster sm 
         JOIN FamilyMaster fm ON sm.FamilyMasterId = fm.Id 
         JOIN FamilyDetail fd ON fm.id = fd.FamilyMasterId 
         JOIN TravelMaster tm ON fd.Id = tm.FamilyDetailId 
       GROUP BY Username 
      ) tm ON sm.Username = tm.Username 
     JOIN (SELECT Username , 
         COUNT(td.id) TravelDetail 
       FROM  SurveyMaster sm 
         JOIN FamilyMaster fm ON sm.FamilyMasterId = fm.Id 
         JOIN FamilyDetail fd ON fm.id = fd.FamilyMasterId 
         JOIN TravelMaster tm ON fd.Id = tm.FamilyDetailId 
         JOIN TravelDetail td ON tm.Id = td.TravelMasterId 
       GROUP BY Username 
      ) td ON sm.Username = td.Username 
GROUP BY sm.Username , 
     fd.FamilyDetail , 
     tm.TravelMaster , 
     td.TravelDetail; 
+0

谢谢..但是如果我们谈论性能,最好的选择是什么,因为这将成为我的项目的关键绩效指标 –

+0

最简单的解决方案是道德败坏,即添加用户ID外键列在每个表中。 – Yared

+0

只是为了知识,你认为将userId添加到每个表将是一个最佳实践?我不是专家,但我认为我们应尽可能减少数据冗余。 –

相关问题