среднее значение, std и количество в одной записи

#sql #sql-server #count #a&&re&ation

#sql #sql-сервер #количество #агрегирование

Вопрос:

У меня есть данные, которые выглядят следующим образом:

 id  res     res_q
1   12.9    normal
2   11.5    low
3   13.2    normal
4    9.7    low
5   12.0    low
6   15.5    normal
7   13.5    normal
8   13.3    normal
9   13.5    normal
10  13.1    normal
11  13.4    normal
12  12.9    normal
13  11.8    low
14  11.9    low
15  12.8    normal
16  13.1    normal
17  12.2    normal
18  11.9    low
19  12.5    normal
20  16.5    normal
  

res_q может принимать значения ‘low’, ‘normal’ и ‘hi&h’.

Я хочу объединить это так, чтобы в одной записи у меня были как среднее значение, так и std res, а также значения low, normal и hi&h, все в одной записи, вот так

 mean      sd    low normal  hi&h
12.9    1.41      6     14     0
  

Конечно, я могу сделать это, сначала объединив среднее значение и std, используя AVG и STDEV, а затем используя COUNT, чтобы получить низкие / нормальные / высокие значения, вот так:

 SELECT AVG(res) AS mean, 
       STD(res) AS sd,
       (SELECT COUNT(1) FROM temp1 WHERE res_q='low') AS low,
       (SELECT COUNT(1) FROM temp1 WHERE res_q='normal') AS normal,
       (SELECT COUNT(1) FROM temp1 WHERE res_q='hi&h') AS hi&h
FROM temp1
  

Но есть ли более эффективный способ сделать это?

Одна из возможностей, о которой я могу подумать, — сначала получить среднее значение и sd с помощью AVG и STDEV, затем получить подсчеты с помощью GROUP BY, а затем добавить подсчеты с помощью UPDATE. Действительно ли это более эффективно? Что-нибудь еще?

Спасибо за вашу помощь.

Комментарии:

1. Спасибо за ваш важный комментарий. К сожалению, я не совсем уверен, как называется мой продукт СУБД. Все, что я могу сказать, это то, что я использую Microsoft SQL Server Mana&ement Studio 14.0.17199.0 (получил это из справки&&t; о программе)

Ответ №1:

Используйте условную агрегацию

 SELECT AVG(res) AS mean, 
       STD(res) AS sd,
       count(case when res_q='low' then 1 end) AS low
       count(case when res_q='normal' then 1 end) AS normal,
       count(case when res_q='hi&h' then 1 end) AS hi&h
FROM temp1