Estou lutando com uma consulta SQL que lista os hosts que estão offline.
Problema
O problema ocorre quando preciso listar hosts que não possuem nenhuma porta aberta (status = 0), portanto, olhando a tabela na parte inferior, deve listar apenas 192.168.1.2, porém lista todos os hosts.
Eu tentei muitas consultas + subconsultas sem sorte ainda, ficaria grato se você pudesse me dizer onde estou errando e me informar qual é a consulta correta. Obrigada.
MariaDB [scanner]> SELECT DISTINCT ports.ip_add FROM ports WHERE ports.status = FALSE;
+-------------+
| ip_add |
+-------------+
| 192.168.1.1 |
| 192.168.1.2 |
| 192.168.1.3 |
+-------------+
Consulta de trabalho semelhante
Esta consulta lista todos os hosts que possuem pelo menos uma porta aberta (status = 1), ótimo.
MariaDB [scanner]> SELECT DISTINCT ports.ip_add FROM ports WHERE ports.status = TRUE;
+-------------+
| ip_add |
+-------------+
| 192.168.1.1 |
| 192.168.1.3 |
+-------------+
Mesa
MariaDB [scanner]> SELECT * FROM ports LIMIT 9;
+--------+-------------+----------+------------+---------------------+
| id | ip_add | port | status | probe_meta |
+--------+-------------+----------+------------+---------------------+
| 1 | 192.168.1.1 | 22 | 1 | 2016-03-29 00:01:00 |
| 2 | 192.168.1.1 | 21 | 1 | 2016-03-29 00:02:00 |
| 3 | 192.168.1.1 | 23 | 1 | 2016-03-29 00:03:00 |
| 4 | 192.168.1.2 | 22 | 0 | 2016-03-29 00:05:00 |
| 5 | 192.168.1.2 | 21 | 0 | 2016-03-29 00:06:00 |
| 6 | 192.168.1.2 | 23 | 0 | 2016-03-29 00:07:00 |
| 7 | 192.168.1.3 | 22 | 1 | 2016-03-29 00:09:00 |
| 8 | 192.168.1.3 | 21 | 0 | 2016-03-29 00:10:00 |
| 9 | 192.168.1.3 | 23 | 0 | 2016-03-29 00:11:00 |
+--------+-------------+----------+------------+---------------------+
Outra forma de fazer isso seria agregar a
status
coluna porip_addr
, onde o total é igual a zero.O banco de ensaio:
A pergunta:
Os resultados:
SQLFiddleName
A sintaxe do MySQL não é minha especialidade, mas esta é a maneira lógica de fazer isso no T-SQL, então você entende como precisa filtrar:
Esta é a maneira rápida e suja, embora existam maneiras mais eficientes de fazer isso se o conjunto de dados for grande, mas esperamos que você tenha uma ideia.
O problema que você descreve é conhecido como divisão relacional. Em matemática você poderia dizer algo como:
FORALL x: p(x)
. Isso porém não é possível expressar em SQL, então teremos que transformar a formulação do problema. Uma maneira comum é dizer que: oNOT EXISTS x:NOT p(x)
que pode ser expresso em SQL. No entanto, no seu caso, provavelmente é mais fácil apenas contar as portas com status 0 e comparar com o número total de portas: