Предположим, в моей базе данных PostgreSQL есть таблица
-----------+-----------------------------
IP | inet
timestamp | timestamp
ports | integer REFERENCES other_table_does_not_matter
hostname | character varying
каждый IP проверяется каждый час.
Я хочу сгруппировать количество (IP), то есть суммарную ежедневную недоступность по дням, как показано ниже:
SELECT timestamp::date AS date, COUNT (DISTINCT IP) AS count
FROM ip_check WHERE ports=9 AND ip NOT IN (SELECT IP FROM ip_check WHERE hostname <> '')
GROUP BY timestamp::date
ORDER BY timestamp::date ASC;
но есть дополнительное условие. Мне нужно исключить IP, который был доступен / доступен даже в течение короткого времени (в моем случае имя хоста <> '' означает, что IP был доступен):
... AND IP NOT IN (SELECT ... WHERE hostname <> '' AND DATE(timestamp)='2019-01-25')
Другими словами. Я хотел бы запустить один SELECT (показанный ниже) для ряда дат и группировать результаты по дням.
SELECT COUNT(DISTINCT IP)
FROM ip_check
WHERE ports=9 AND DATE(timestamp)='2019-01-25'
AND IP NOT IN
(SELECT IP
FROM ip_check
WHERE hostname <> '' AND DATE(timestamp)='2019-01-25');
Пример данных:
(ip;timestamp;ports;hostname)
(1.1.1.1;2019-01-24 10:11;9;'')
(1.1.1.1;2019-01-24 11:11;9;'hostA')
(1.1.1.1;2019-01-24 1:11;9;'')
(1.1.1.1;2019-01-24 2:11;9;'')
(1.1.1.1;2019-01-24 3:11;9;'')
(1.1.1.1;2019-01-24 4:11;9;'')
(2.1.1.1;2019-01-24 10:11;9;'')
(3.1.1.1;2019-01-24 10:11;9;'hostC')
(1.1.1.1;2019-01-25 10:11;9;'')
(1.1.1.1;2019-01-25 11:11;9;'')
(1.1.1.1;2019-01-25 1:11;9;'hostA')
(2.1.1.1;2019-01-25 10:11;9;'')
(3.1.1.1;2019-01-25 10:11;9;'')
Желаемый вывод:
data | count
------------+-------
2019-01-24 | 1
2019-01-25 | 2
(2 rows)
Объяснение:
- 2019-01-24 - только 1 IP (2.1.1.1) полностью недоступен
- 2019-01-25 - 2 IP (2.1.1.1, 3.1.1.1) полностью недоступны