Группа запросов PostgreSQL по двум «параметрам» - PullRequest
0 голосов
/ 11 мая 2018

Я пытался выяснить следующий запрос PostgreSQL безуспешно уже два дня.

Допустим, у меня есть следующая таблица:

| date         | value  |
-------------------------
| 2018-05-11   |  0.20  |
| 2018-05-11   | -0.12  |
| 2018-05-11   |  0.15  |
| 2018-05-10   | -1.20  |
| 2018-05-10   | -0.70  |
| 2018-05-10   | -0.16  |
| 2018-05-10   |  0.07  |

И мне нужнонайти запрос для подсчета положительных и отрицательных значений в день:

| date         | positives  | negatives  |
------------------------------------------
| 2018-05-11   | 2          | 1          |
| 2018-05-10   | 1          | 3          |

Мне удалось выяснить запрос, чтобы извлечь только положительные и отрицательные значения, но не оба одновременно:

SELECT to_char(table.date, 'DD/MM') AS date
      COUNT(*)                     AS negative
FROM table
WHERE table.date >= DATE(NOW() - '20 days' :: INTERVAL) AND
      value < '0'
GROUP BY to_char(date, 'DD/MM'), table.date
ORDER BY table.date DESC;

Может кто-нибудь помочь?Это сводит меня с ума.Спасибо.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Я бы просто сделал:

select date_trunc('day', t.date) as dte, 
       sum( (value < 0)::int ) as negatives,
       sum( (value > 0)::int ) as positives
from t
where t.date >= current_date - interval '20 days' 
group by date_trunc('day', t.date),
order by dte desc;

Примечания:

  • Я предпочитаю использовать date_trunc() для приведения к строке для удаления компонента времени.
  • Вам не нужно использовать now() и конвертировать в дату.Вы можете просто использовать current_date.
  • Преобразование строки в интервал кажется неудобным, когда вы можете указать интервал с помощью ключевого слова interval.
0 голосов
/ 11 мая 2018

Используйте предложение FILTER с агрегатной функцией.

SELECT to_char(table.date, 'DD/MM') AS date,
      COUNT(*) FILTER (WHERE value < 0) AS negative,
      COUNT(*) FILTER (WHERE value > 0) AS positive
FROM table
WHERE table.date >= DATE(NOW() - '20 days'::INTERVAL)
GROUP BY 1
ORDER BY DATE(table.date) DESC
...