Zliczenie rekordów po dniu, nawet gdy brak wpisów z dnia,

0

Witam.

W projekcie (postgre) posiadam tabelę locations, upraszczając:

CREATE TABLE locations
(
  id serial NOT NULL,
  "timestamp" timestamp without time zone
  CONSTRAINT locations_pkey PRIMARY KEY (id)
)

Potrzebuję zliczyć ilość wpisów w tabeli z zadanego przedziału czasowego, grupując po dniu, co jest raczej trywialne:

SELECT to_timestamp(to_char(l.timestamp, 'YYYY-MM-DD'),'YYYY-MM-DD') AS x, count(*) 
FROM locations l 
WHERE l.timestamp BETWEEN to_timestamp('2012-02-23','YYYY-MM-DD') AND to_timestamp('2012-03-21','YYYY-MM-DD')
GROUP BY x ORDER BY x

Chciałbym jednak, aby zapytanie zwracało wyniki, dla każdego dnia z zadanego przedziału - dla dni, w których nie było wpisów w tabeli chcę dostać:

x | count
2012-04-05 0000+02 | 0

0

Wygeneruj sobie listę dni przy pomocy generate_series a potem zliczaj ile jest wierszy pasujących do każdej daty z listy.

0

Okay, pomogło. Kompletne zapytanie, to:

SELECT x.gs,COUNT(l.timestamp) FROM (
SELECT generate_series('2012-02-23'::timestamp, '2012-03-21', '1 day') AS gs
) AS x
LEFT JOIN locations l ON x.gs = l.timestamp::date
GROUP BY x.gs ORDER BY x.gs

Czas wykonania tego zapytania ~60 ms.

Moja tabela locations zawiera jeszcze pole user_id. Chciałbym zrobić tak, aby w momencie w którym użytkownik wybierze w formularzu na stronie user_id,
pokazać mu wyniki od pierwszego do ostatniego wpisu w locations dla danego user_id, zakładając że grupujemy jw.

Zrobiłem to tak (casey uzupełnia kod java, to co podałem to przykładowe zapytanie wygenerowane w programie):

SELECT x.gs,COUNT(l.timestamp) FROM (
	SELECT generate_series(y.min , y.max, '1 day') AS gs FROM (
		SELECT MIN(l.timestamp::date) AS min, MAX(l.timestamp::date) AS max
		FROM locations l
		WHERE CASE WHEN 23>-1 THEN l.user_id=23 ELSE TRUE END
	) AS y
) AS x
LEFT JOIN locations l ON x.gs = l.timestamp::date
WHERE CASE WHEN 23>-1 THEN l.user_id=23 ELSE TRUE END
GROUP BY x.gs ORDER BY x.gs

Zapytanie działa poprawnie, ale jego czas wykonania to już 450 (user_id > -1, czyli gdy podano użytkownika)-800(gdy nie wybrano użytkownika) ms,
jakieś pomysły jak optymalizować ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1