рассчитать стандартное отклонение внутри сводной таблицы - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть сводный запрос, который выглядит как показано ниже, получая count и AVG строк, которые работают просто отлично, но не стандартное отклонение, STD.

Как я могу изменить SQLниже, чтобы получить STD?

SELECT mid                             as mID,
   round((x.qty_sum / x.qty_count), 5) as qtAVG,
   round(x.qty_stddev, 5)              as qtSTDDEV,
   x.qty_count                         as qtCOUNT,
   round((x.rel_sum / x.rel_count), 5) as relAVG,
   round(x.rel_stddev, 5)              as relSTDDEV,
   x.rel_count                         as relCOUNT,
FROM (SELECT mid,
         SUM(CASE WHEN (mt = "qt") THEN 1 ELSE 0 END)   as qty_count,
         SUM(CASE WHEN (mt = "qt") THEN rt ELSE 0 END)  as qty_sum,
         STD(CASE WHEN (mt = "qt") THEN rt ELSE 0 END)  as qty_stddev
         SUM(CASE WHEN (mt = "rel") THEN 1 ELSE 0 END)  as rel_count,
         SUM(CASE WHEN (mt = "rel") THEN rel ELSE 0 END) as rel_sum,
         STD(CASE WHEN (mt = "rel") THEN rel ELSE 0 END) as rel_stddev
  FROM t_r
  GROUP BY mid) x;

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Я думаю, что ваша единственная проблема - ELSE 0.Вы просто хотите NULL значения, потому что они будут игнорироваться:

SELECT mid                                 as mID,
       round((x.qty_sum / x.qty_count), 5) as qtAVG,
       round(x.qty_stddev, 5)              as qtSTDDEV,
       x.qty_count                         as qtCOUNT,
       round((x.rel_sum / x.rel_count), 5) as relAVG,
       round(x.rel_stddev, 5)              as relSTDDEV,
       x.rel_count                         as relCOUNT,
FROM (SELECT mid,
             SUM( mt = 'qt' )   as qty_count,
             SUM(CASE WHEN mt = 'qt' THEN rt END)  as qty_sum,
             STD(CASE WHEN mt = 'qt' THEN rt END)  as qty_stddev,
             SUM( mt = 'rel' ) as rel_count,
             SUM(CASE WHEN mt = 'rel' THEN rel END) as rel_sum,
             STD(CASE WHEN mt = 'rel' THEN rel END) as rel_stddev
      FROM t_r
      GROUP BY mid
     ) x;

Обратите внимание на некоторые другие изменения:

  • Я упростил логику для подсчетов, чтобы удалить CASE выражение.При этом используется расширение MySQL, которое обрабатывает логические значения как числа с 1 для true и 0 для false.
  • Я заменил двойные кавычки одинарными кавычками.Одинарные кавычки являются стандартным разделителем для строк.
  • Я удалил предложения ELSE.Функции агрегирования игнорируют значения NULL, поэтому это должно решить вашу проблему.
0 голосов
/ 11 декабря 2018

Похоже, вы пытаетесь перехитрить MySQL с этим подзапросом.Что касается того, вам не нужен этот дополнительный уровень сложности, просто используйте простой агрегированный запрос с предложением WHERE, который фильтрует записи, имеющие mt = "qt".

SELECT 
    mid as mID,
    ROUND(AVG(rt), 5) as qtAVG,
    ROUND(STD(rt), 5) as qtSTDDEV,
    COUNT(*) as qtCOUNT,
FROM t_r
WHERE mt =  "qt"
GROUP BY mt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...