2010-05-16 616 views
5

任何人都可以帮助我使用Apache Derby SQL中的SQL查询来获取“简单”计数。SQL聚合查询问题

给定一个表ABC看起来像这样...

  
    id a b c 
    1 1 1 1 
    2 1 1 2 
    3 2 1 3 
    4 2 1 1 
** 5 2 1 2 ** 
** 6 2 2 1 ** 
    7 3 1 2 
    8 3 1 3 
    9 3 1 1 

我如何编写一个查询得到的计数怎么可能的不同值“A”兼得(B = 1和c = 2)AND(b = 2和c = 1)得到正确的结果1.(两行标记符合条件并且都具有a = 2的值,在该表中只有1个不同的值匹配标准)

棘手的是,(b=1 and c=2) AND (b=2 and c=1)显然是相互排斥,当应用到单个行。 ..所以如何将该表达式应用于多行不同值的行?

这些查询都是错误的,而是为了说明什么,我试图做...
SELECT DISTINCT COUNT(a) WHERE b=1 AND c=2 AND b=2 AND c=1 ...
。(0)没有去,因为相互排斥
SELECT DISTINCT COUNT(a) WHERE b=1 AND c=2 OR b=2 AND c=1 ...
。(3)让我错了结果。
SELECT COUNT(a) (CASE WHEN b=1 AND c=10 THEN 1 END) FROM ABC WHERE b=2 AND c=1
。(0)没有去,因为相互排斥

干杯, 菲尔。

+0

(a,b,c)是否是唯一的?换句话说,是否可以有两行具有不同的ID,但a,b和c的值相同? – 2010-05-16 22:16:59

回答

7

我假设(a,b,c)是唯一的。要做到这一点的方法之一是使用自联接:

SELECT COUNT(*) 
FROM ABC T1 
JOIN ABC T2 
ON  T1.a = T2.a 
WHERE T1.b = 1 AND T1.c = 2 
AND T2.b = 2 AND T2.c = 1 

这个工程概念如下:

  • 查找所有满足(b,c) = (1,2)
  • 查找所有满足(b,c) = (2,1)
  • 行的行
  • 当a相同时加入上述两组。
  • 计算连接结果中的行数。

的另一种方式,这可能是更容易理解是使用子查询:

SELECT COUNT(*) 
FROM ABC 
WHERE a IN (SELECT a FROM ABC 
      WHERE b = 2 
      AND c = 1) 
AND b = 1 
AND c = 2 

注:如果有可复制的(A,B,C),然后代替SELECT COUNT(*)使用SELECT COUNT(DISTINCT T1.a)值在第一个查询中,并在第二个SELECT COUNT(DISTINCT a)

这些查询在MySQL中测试,而不是Apache Derby,但我希望它们也能在那里工作。

+0

感谢大家的答案,特别是给你标记以及迅速准确的答案。我尝试了你的第二个建议,它完美地工作。 现在,因为我实际上正在尝试编写交叉表报表,所以我想知道是否必须为b和c值的每个组合都有一个查询,或者我是否可以以某种方式在一个查询中完成所有操作。 干杯,菲尔。 – Phil 2010-05-17 10:19:49

0

棘手的一点是,当施加到单个行

正是这样(B = 1和c = 2)和(b = 2和c = 1)是明显相互排斥的。在考虑记录的集合时,需要行的不同“a”值的数量,其中 OR(b = 2 and c = 1)。试试这个:

SELECT COUNT(DISTINCT a) FROM "abc" WHERE (b=1 OR c=2) OR (b=2 OR c=1) 
+0

应该在括号内的最后一个查询中是“AND”。 – 2010-05-17 01:10:54

1

根据Apache Derby's SQL support page,Mark的第二个查询确实应该被Apache Derby支持。

SELECT COUNT(DISTINCT a) FROM ABC 
WHERE b = 1 AND c = 2 
    AND a IN (SELECT a FROM ABC WHERE b = 2 AND c = 1); 

除了比自联接版本更易于阅读,它还应该更快,因为您可以避免必须执行JOIN的开销。