Blogi deweloperów PLD/FreeBSD

3.1TomaszTrojanowski replied 2 weeks, 2 days after the incident

Przecież SELECT id_process FROM task WHERE status = 'completed' GROUP BY id_process; zwróci liste procesów które mają przynajmniej jedno zadanie zakończone, a nie liste procesów, w których wszystkie zadania zostały zakończone. Nie widzisz tego?

Cały problem leży w tym, żeby uzyskać listę procesów, w których wszystkie zadania się zakończyły, użycie WHERE w tym przypadku nic nie da, bo przed wykonaniem funkcji COUNT ograniczy zbiór poczatkowy do zadań które się nie zakończyły (w przypadku WHERE status <> 'completed') albo do zadań które się zakończyły w przypadku WHERE status = 'completed'). Czyli używając WHERE status = 'completed' nie wiemy czy są w tak ograniczonej tabeli rekordy z status <> 'completed'

Na przykładzie będzie prościej. Przyjmijmy, że w tabela "task" wygląda tak (pominąłem pierwsze pole bo jest nieistotne w tym wypadki):

id_process status
1 none
1 running
2 completed
2 completed
3 completed
3 running
Moje
SELECT id_process, COUNT(status != 'completed' OR NULL) AS count FROM task
GROUP BY id_process HAVING count = 0;
zwróci:
id_process count
2 0
Twoje
SELECT id_process, COUNT(*) AS count FROM task WHERE status = 'completed' GROUP BY id_process;
zwróci
id_process count
2 2
3 1
Oczywiscie count jest nieistotne, ale te zapytania zwracaja zupełnie różną liste procesów.

Rozumiesz juz o co chodzi czy mam tłumaczyć dalej. … reply

2 Comments

3.1.1MarcinGajda replied 2 weeks, 2 days after the incident

Wszystkie...

No tak – mają być wszystkie. Wobec tego biję się w piersi, rzeczywiście moje zapytanie nie daje poprawnego wyniku.

Mimo wszystko napisałbym to inaczej:

SELECT id_process
  FROM task
  WHERE status = 'completed'
  GROUP BY id_process
EXCEPT
SELECT id_process
  FROM task
  WHERE status <> 'completed'
  GROUP BY id_process

To zapytanie wciąż będzie szybsze w planie wykonania od Twojego. … reply

3.1.1.1TomaszTrojanowski, 11 hours, 4 minutes later 11 hours, 4 minutes later
Nie jestem do końca przekonany, czy będzie szybsze. Nawet jeżeli tak, to najprawdopodobniej
SELECT DISTINCT id_process AS p1 FROM task
  WHERE status = 'completed' AND
  NOT EXISTS (SELECT * FROM task WHERE status <> 'completed'  AND id_process = p1);
będzie jeszcze szybsze. Ale to nie o to chodzi. … reply

Leave a Reply

You may have to login or register to comment if you haven't already.

About

Tomasz Trojanowski mieszka w Łańcucie, wraz z żoną Iwoną i synami Jakubem i Arkadiuszem. Pracuje jako administrator serwerów internetowych. W wolnych chwilach zajmuje się projektem PLD/FreeBSD.

Categories

1
1
6

r1 – 16 Feb 2007 – 09:28:14 – Main.TomaszTrojanowski
Copyright © 1999-2008. Zawartość tego serwisu jest własnością osób współpracujących. Wyślij pomysły, pytania dotyczące serwisu.