加入三个表以获取MySQL中的摘要数据

时间:2016-07-01 16:18:44

标签: mysql

我在SQL上遇到了新的问题并且有一个问题,我相信可以通过一些SQL查询来完成...如果我更好地理解了Joins。

我有三个表,每个表通过主键/外键链接到另一个表。 实际情况是最深的表中有大约60,000条记录,但为了简单起见,您可以使用以下方式重新创建表结构:

CREATE DATABASE IF NOT EXISTS test;
USE test;
CREATE TABLE IF NOT EXISTS FileData (fd_ID_pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Analyst VARCHAR(2) NOT NULL);
INSERT INTO FileData (Analyst) VALUES('AD'), ('LS'), ('MM'), ('MM'), ('MM'), ('LS'), ('LS'), ('AD'), ('MM');
CREATE TABLE IF NOT EXISTS IndData (sp_ID_pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY, fd_ID_fk INT NOT NULL, IndNum INT NOT NULL, FOREIGN KEY (fd_ID_fk) REFERENCES FileData (fd_ID_pk));
INSERT INTO IndData (fd_ID_fk, IndNum) VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (2,1), (2,2), (2,3), (2,4), (2,5), (2,6), (2,7), (2,8), (2,9), (2,10), (3,1), (3,2), (3,3), (3,4), (3,5), (3,6), (3,7), (3,8), (3,9), (3,10), (3,11), (3,12), (3,13), (3,14), (3,15), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6), (4,7), (4,8),  (5,1), (5,2), (5,3), (5,4), (6,1), (6,2), (6,3), (6,4), (6,5), (6,6), (6,7), (7,1), (7,2), (7,3), (7,4), (7,5), (7,6), (7,7), (8,1), (8,2), (8,3), (8,4), (8,5), (8,6), (8,7), (8,8), (9,1), (9,2), (9,3), (9,4), (9,5);
CREATE TABLE IF NOT EXISTS FinData (sp_1_fk INT NULL, sp_2_fk INT NULL, sp_3_fk INT NULL, FOREIGN KEY (sp_1_fk) REFERENCES IndData (sp_ID_pk), FOREIGN KEY (sp_2_fk) REFERENCES IndData (sp_ID_pk), FOREIGN KEY (sp_3_fk) REFERENCES IndData (sp_ID_pk));
INSERT INTO FinData (sp_1_fk, sp_2_fk, sp_3_fk) VALUES (57,null,64), (18,64,67), (null,11,35), (null,58,35), (null,null,24), (18,null,null), (null, 6,26), (34,null, 8), (null, 8,null), (59,68,28), (null, 1,17), (39,55,null), (65,58, 7), (null,null,10), (54, 6,null), (53,null,67), (27,19,41), (null,57, 5), ( 6,31,17),( 4,64,25), (38,13,58), (55,null, 2), (66,null, 4), (10,10,null), (40,61,46), (null,null,52), ( null,39,46), (null,11,32), (12,null,39), (56,44,21),(22,25,53), (37,null,null), (12,null,49), (43, null,13), (19,17,26), (46, 9,44), (null,13,null), (53,null, 6), (32,30,null)

基本上,第一个表是文件列表,每个文件都有一个与之关联的分析师。每位分析师可以有多个文件。

fd_ID_pk   Analyst
1         AD
2         LS
3         MM
4         MM
etc

第二个表是该文件中的数据条目列表,每个记录都有一个键。

sp_ID_pk   fd_ID_fk   IndNum
1          1          1
2          1          2
3          1          3
4          1          4
5          1          5
6          1          6
7          2          1
8          2          2
etc

第三个表格对我来说很复杂。这有三列,每列都链接到第二个表中的记录,可以为null

sp_1_fk   sp_2_fk   sp_3_fk
12                  39
56        44        21
22        25        53
37                      
12                  49
43                  13
19        17        26

我需要的是一个汇总表,显示每个分析师的文件和IndData和FinData的数量。

我已经得到了这个给了我每个分析师的总数,但他们看起来并不正确:

SELECT filedata.Analyst, COUNT(filedata.Analyst) as 'count'
FROM filedata
JOIN inddata
ON filedata.fd_ID_pk = inddata.fd_ID_fk
JOIN findata
ON findata.sp_1_fk = inddata.sp_ID_pk OR findata.sp_2_fk = inddata.sp_ID_pk OR findata.sp_3_fk = inddata.sp_ID_pk
GROUP BY filedata.Analyst

然而,理想情况下,我试图解决这个问题:

Analyst   TotalFiles   FilesUsed   TotalInd   IndUsed
AD        2            2           14         10        
LS        3            3           24         16
MM        4            4           32         24

有一些疑问......任何建议都会受到赞赏!

2 个答案:

答案 0 :(得分:0)

首先尝试获得结果连接表3和2

SELECT ID.sp_ID_pk, COUNT(*) AS VAL , COUNT(distinct IndNum) AS IDUSED
  FROM IndData ID 
  LEFT JOIN FinData FD ON FD.sp_1_fk = ID.sp_ID_pk 
  LEFT JOIN FinData FDD ON FDD.sp_2_fk = ID.sp_ID_pk 
  LEFT JOIN FinData FDDD ON FDDD.sp_3_f k= ID.sp_ID_pk 
GROUP BY ID.sp_ID_pk;



 +----------+-----+--------+
    | sp_ID_pk | VAL | IDUSED |
    +----------+-----+--------+
    |        1 |   1 |      1 |
    |        2 |   1 |      1 |
    |        3 |   1 |      1 |
    |        4 |   1 |      1 |
    |        5 |   1 |      1 |
    |        6 |   2 |      1 |
    |        7 |   1 |      1 |
    |        8 |   1 |      1 |
    |        9 |   1 |      1 |
    |       10 |   1 |      1 |
    |       11 |   2 |      1 |
    |       12 |   2 |      1 |
    |       13 |   2 |      1 |
    |       14 |   1 |      1 |
    |       15 |   1 |      1 |
    |       16 |   1 |      1 |
    |       17 |   2 |      1 |
    |       18 |   2 |      1 |
    |       19 |   1 |      1 |
    |       20 |   1 |      1 |
    |       21 |   1 |      1 |
    |       22 |   1 |      1 |
    |       23 |   1 |      1 |
    |       24 |   1 |      1 |
    |       25 |   1 |      1 |
    |       26 |   2 |      1 |
    |       27 |   1 |      1 |
    |       28 |   1 |      1 |
    |       29 |   1 |      1 |
    |       30 |   1 |      1 |
    |       31 |   1 |      1 |
    |       32 |   1 |      1 |
    |       33 |   1 |      1 |
    |       34 |   1 |      1 |
    |       35 |   2 |      1 |
    |       36 |   1 |      1 |
    |       37 |   1 |      1 |
    |       38 |   1 |      1 |
    |       39 |   1 |      1 |
    |       40 |   1 |      1 |
    |       41 |   1 |      1 |
    |       42 |   1 |      1 |
    |       43 |   1 |      1 |
    |       44 |   1 |      1 |
    |       45 |   1 |      1 |
    |       46 |   2 |      1 |
    |       47 |   1 |      1 |
    |       48 |   1 |      1 |
    |       49 |   1 |      1 |
    |       50 |   1 |      1 |
    |       51 |   1 |      1 |
    |       52 |   1 |      1 |
    |       53 |   2 |      1 |
    |       54 |   1 |      1 |
    |       55 |   1 |      1 |
    |       56 |   1 |      1 |
    |       57 |   1 |      1 |
    |       58 |   2 |      1 |
    |       59 |   1 |      1 |
    |       60 |   1 |      1 |
    |       61 |   1 |      1 |
    |       62 |   1 |      1 |
    |       63 |   1 |      1 |
    |       64 |   2 |      1 |
    |       65 |   1 |      1 |
    |       66 |   1 |      1 |
    |       67 |   2 |      1 |
    |       68 |   1 |      1 |
    |       69 |   1 |      1 |
    |       70 |   1 |      1 |
    +----------+-----+--------+
    70 rows in set (0.01 sec)

然后将其加入下表

mysql> select * from FileData;
+----------+---------+
| fd_ID_pk | Analyst |
+----------+---------+
|        1 | AD      |
|        2 | LS      |
|        3 | MM      |
|        4 | MM      |
|        5 | MM      |
|        6 | LS      |
|        7 | LS      |
|        8 | AD      |
|        9 | MM      |
+----------+---------+
9 rows in set (0.00 sec)

你会得到你想要的东西

答案 1 :(得分:0)

每当查询中涉及多个1对多关系时,大多数聚合都需要在子查询中计算,以防止不同的“多个”乘以预先聚合的结果计数。