SQL聚合查询问题

时间:2010-05-16 22:07:52

标签: sql derby

任何人都可以帮助我在Apache Derby 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个不同的a值与条件匹配)

棘手的一点是(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)不相互排斥

干杯, 菲尔。

3 个答案:

答案 0 :(得分: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,但我希望它们也能在那里工作。

答案 1 :(得分:1)

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

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的开销。

答案 2 :(得分:0)

  

棘手的一点是(b = 1和c = 2)AND(b = 2和c = 1)在应用于单行时显然是互斥的

确实如此。在考虑记录的时,您需要(b = 1 and c = 2) OR (b = 2 and c = 1)行的不同“a”值的数量。试试这个:

SELECT COUNT(DISTINCT a) FROM "abc" WHERE (b=1 OR c=2) OR (b=2 OR c=1)
相关问题