2010-05-16 19 views
5

Kann mir jemand mit einer SQL-Abfrage in Apache Derby SQL helfen, um eine "einfache" Anzahl zu erhalten.SQL-Aggregat Abfrage Frage

eine Tabelle ABC gegeben, der so aussieht ...

  
    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 

Wie kann ich eine Abfrage schreiben, eine Zählung, wie kann verschiedene Werte von ‚a‘ beide = 1 und c (b müssen erhalten = 2) AND (b = 2 und c = 1), um das korrekte Ergebnis von 1 zu erhalten (die zwei markierten Zeilen entsprechen den Kriterien und beide haben einen Wert von a = 2, es gibt nur einen eindeutigen Wert von a in dieser Tabelle) entsprechen den Kriterien)

Das schwierige Bit ist, dass (b=1 and c=2) AND (b=2 and c=1) sich offensichtlich gegenseitig ausschließen, wenn sie auf eine einzelne Zeile angewendet werden. .. also wie verwende ich diesen Ausdruck über mehrere Zeilen mit unterschiedlichen Werten für eine?

Diese Abfragen sind falsch, aber zu veranschaulichen, was ich versuche zu tun ...
SELECT DISTINCT COUNT(a) WHERE b=1 AND c=2 AND b=2 AND c=1 ...
.. (0) nicht gehen als sich gegenseitig ausschließende
SELECT DISTINCT COUNT(a) WHERE b=1 AND c=2 OR b=2 AND c=1 ...
.. (3) wird mir die falsche Ergebnis.
SELECT COUNT(a) (CASE WHEN b=1 AND c=10 THEN 1 END) FROM ABC WHERE b=2 AND c=1
.. (0) nicht als sich gegenseitig ausschließende

Cheers, Phil gehen.

+0

Ist (a, b, c) einzigartig? Mit anderen Worten, kann es zwei Zeilen mit unterschiedlichen IDs geben, aber die gleichen Werte von a, b und c? –

Antwort

7

Ich nehme an, dass (a, b, c) einzigartig ist. Eine Möglichkeit, dies zu tun, ist ein Selbst verwenden beitreten:

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 

Dieses Konzept funktioniert wie folgt:

  • alle Zeilen finden, die erfüllen (b,c) = (1,2)
  • alle Zeilen finden, die erfüllen (b,c) = (2,1)
  • Verbinden Sie die beiden oben genannten Sätze, wenn a gleich ist.
  • Die Anzahl der Zeilen im verknüpften Ergebnis zählen.

Eine alternative Möglichkeit, die einfacher sein könnte, zu verstehen, ist ein subselect zu verwenden:

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

Hinweis: Wenn kann es Werte von (a, b, c) dann statt SELECT COUNT(*) Gebrauch vervielfältigt SELECT COUNT(DISTINCT T1.a) in der ersten Abfrage und SELECT COUNT(DISTINCT a) in der zweiten.

Diese Abfragen werden in MySQL getestet, nicht Apache Derby, aber ich hoffe, dass sie auch dort funktionieren.

+0

Danke Jeder für die Antworten und vor allem für Sie Mark für die schnelle und genaue Antwort. Ich habe deinen zweiten Vorschlag ausprobiert und es hat perfekt funktioniert. Jetzt, da ich tatsächlich versuche, einen Kreuztabellenbericht zu schreiben, frage ich mich, ob ich für jede Kombination von B- und C-Werten eine Abfrage haben muss oder ob ich alles in einer Abfrage irgendwie tun kann. Prost, Phil. – Phil

0

Der schwierige Bit ist, dass (b = 1 und c = 2) und (b = 2 und c = 1) ist offensichtlich gegenseitig ausschließen, wenn an eine einzelne Zeile angelegt

Genau so. Wenn Sie an die Gruppe der Datensätze denken, möchten Sie die Anzahl der verschiedenen "a" -Werte für Zeilen, wobei OR(b = 2 and c = 1).Versuchen Sie folgendes:

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

sollte 'AND' in der abschließenden Abfrage innerhalb der Klammer sein .. –

1

Marks zweite Abfrage in der Tat von Apache Derby unterstützt werden soll, nach Apache Derby's SQL support page.

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); 

Neben leichter ist als die Selbst-Join-Version zu lesen, sollte es auch schneller sein, da Sie den Overhead mit vermeiden einen JOIN zu tun.