从多个表中的一个表计数代码返回0

时间:2013-06-15 17:07:52

标签: sql join count hsqldb

我是SQL和数据库的新手。我正在使用它们来编写学术论文的数据(为各种句子分配相关的信息标签)。我环顾四周,但我对SQL的新见解可能让我错过了寻找答案的正确方法。

我有几个表,我想在给定字段中计算每个表的所有代码实例。在CODES中,我有一系列代码可以根据需要进行更新。其他表格包含使用代码填写的字段。

CODES
ID  GR  SR  CT
1   S
2   A
3   P
4       S
5       DO
6       IO
7           T
8           I
DATA1
ID  IGR ISR ICT
1   S   S   T
2   P   DO  T
3   S   IO  I
4   S   DO  I
DATA2
ID  IGR ISR ICT
1   A   S   T
2   A   S   T
3   P   S   T
4   P   DO  T

EXPECTED RESULTS:
CODES.GR    DATA1.IGR   DATA2.IGR
S           3           0   
A           0           2
P           1           2

我尝试过以下代码:

SELECT "CODES"."CT",
COUNT ("IGR") AS "DATA1.IGR",
COUNT ("IGR") AS "DATA2.IGR"
FROM
"DATA1", "DATA2"
JOIN "CODES" ON "CODES"."GR" = "DATA1"."IGR"
JOIN "CODES" ON "CODES"."GR" = "DATA2"."IGR"
GROUP BY
"CODES"."GR"

给出了每个表每个代码1000个的结果,我希望每个表每个代码少于100个。我试过不同的JOIN无济于事。

每列的代码数量超过15-20。每当我添加代码时,SUM CASE WHEN都不会更新,因此它们不太理想。如果有一种方法可以将查询联合在一起,那么输出的格式不一定是一成不变的。理想的查询从CODES.column中提取所有代码,对所有实例进行计数,并在不使用时返回0。我想在11个表中运行这个单一查询。

我正在使用运行HSQL数据库引擎的OpenOffice Base。

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

尝试

SELECT c.GR, 
       COALESCE(a.IGR1, 0) IGR1,
       COALESCE(b.IGR2, 0) IGR2
  FROM codes c LEFT JOIN
(
  SELECT IGR, COUNT(*) IGR1
    FROM data1
   WHERE IGR IS NOT NULL
   GROUP BY IGR
) a ON c.GR = a.IGR LEFT JOIN
(
  SELECT IGR, COUNT(*) IGR2
    FROM data2
   WHERE IGR IS NOT NULL
   GROUP BY IGR
) b ON c.GR = b.IGR
 WHERE c.GR IS NOT NULL

SELECT c.GR,
       (SELECT COUNT(*) 
          FROM data1 
         WHERE IGR = c.GR) IGR1,
       (SELECT COUNT(*) 
          FROM data2 
         WHERE IGR = c.GR) IGR2
  FROM codes c
 WHERE c.GR IS NOT NULL

两个查询的输出:

| GR | IGR1 | IGR2 |
--------------------
|  S |    3 |    0 |
|  A |    0 |    2 |
|  P |    1 |    2 |

以下是MySql中两个查询的 SQLFiddle 演示。它也应该在HSQLDB上运行得很好。

答案 1 :(得分:0)

这就是我在Oracle中的表现:

SELECT c.gr, d1.cnt, d2.cnt
  FROM codes c
  LEFT JOIN (SELECT igr, COUNT(*) cnt FROM data1 GROUP BY igr) d1 ON c.gr=d1.igr
  LEFT JOIN (SELECT igr, COUNT(*) cnt FROM data2 GROUP BY igr) d2 ON c.gr=d2.igr
;

虽然这会给null =空而不是0.要解决这个问题,你可以这样做:

SELECT c.gr
     , CASE WHEN d1.cnt IS NULL THEN 0 ELSE d1.cnt END
     , CASE WHEN d2.cnt IS NULL THEN 0 ELSE d2.cnt END
  FROM codes c
  LEFT JOIN (SELECT igr, COUNT(*) cnt FROM data1 GROUP BY igr) d1 ON c.gr=d1.igr
  LEFT JOIN (SELECT igr, COUNT(*) cnt FROM data2 GROUP BY igr) d2 ON c.gr=d2.igr
;