Исключить записи в функции AVG SQL? (невозможно использовать WHERE в основном запросе из-за другого счетчика)

мой SQL-запрос, который отлично работает,

select case month(timestamp_iso(STATUSDATE))
        when 1 then 'January'
        when 2 then 'February'
        when 3 then 'March'
        when 4 then 'April'
        when 5 then 'May'
        when 6 then 'Jun'
        when 7 then 'July'
        when 8 then 'August'
        when 9 then 'September' 
        when 10 then 'October'
        when 11 then 'November'
        when 12 then 'December'
    end as Month, 

    count (case when service='ADSL' then 1 end) as  ADSL,
  AVG (timestampdiff(
  4, 
  char(actualfinish - reportdate))/60.00) as efficiecny



from INCIDENT
where   year(STATUSDATE) = year(current_timestamp) 
group by month(timestamp_iso(STATUSDATE))

Я хочу получить за каждый месяц количество услуг с ADSL (делается через первый COUNT) и среднюю разницу во времени в часах для записей, не имеющих услуги ADSL. Поэтому я должен исключить в функции AVG все записи со службой ADSL, но я не могу поместить ее в предложение where.

 where   year(STATUSDATE) = year(current_timestamp) and service!='ADSL' 

потому что моя функция COUNT должна иметь service='ADSL'

Как это решить?

Спасибо


person Veljko    schedule 16.05.2012    source источник


Ответы (3)


Как Агрегатная функция Avg() игнорирует пустые значения, вы можете установить для выражения значение null, если сервис является "ADSL". Затем Avg() будет игнорировать эти записи.

   AVG (case when service != 'ADSL'
             then timestampdiff(4, char(actualfinish - reportdate))/60.00) 
             else null
         end) as efficiency

Вы можете попробовать с объединить:

   COALESCE (AVG (case when service != 'ADSL'
             then timestampdiff(4, char(actualfinish - reportdate))/60.00) 
             else null
         end), 0) as efficiency
person Nikola Markovinović    schedule 16.05.2012
comment
Zdravo Nikola, hvala ti ovo izgleda daje tacan rezultat(provericu jos malo) ali da li posto za jedan mesec dobijam vrednost null da li mogu nekako da za tu vrednost dobijem 0. Zato sto mi je potrebno za iscrtavanje grafika da postoji neka vrednost. Хвала - person Veljko; 16.05.2012
comment
Zdravo Dejane, molim te pogledaj dopunjeni odgovor. - person Nikola Markovinović; 16.05.2012
comment
Никола назалость несто ме зеза. Добиджам результат 0E-18 . Ne znam kako ovo moze negativno da utice na iscrtavanje grafika - person Veljko; 16.05.2012
comment
@Dejan Ne bi trebalo imati veze s ovim gore. Da li dobijaš isti rezultat kad dodaš and service!='ADSL' u where i vratiš originalni AVG()? - person Nikola Markovinović; 16.05.2012
comment
Здраво. U tom slucaju ne dobijam ovaj rezultat 0E-18 . Dobijam OK rezultat u tom slucaju jedino sto mi tada ne prebroji ADSL servise. - person Veljko; 16.05.2012
comment
A sada, kad vratiš merge i makneš and service!='ADSL' ako promijeniš 0 u npr. 100, da li dobiješ neku zbunjujuću brojku? - person Nikola Markovinović; 16.05.2012
comment
radi u BIRT-u lepo prikazuje 0 i sa onim COALESCE... . hvala Nikola puno...mozes samo da mi kazes sta radi ova funkcija nisam je vidjao pre? хвала,ПОЗДРАВ!!!! - person Veljko; 17.05.2012
comment
Ćao Dejane, drago mi je što smo uspjeli. Za объединить имаш ссылку гор, а укратко на враче први не нуль из списка параметров; ако AVG() vrati neku brojku onda daje tu brojku, ako vrati null onda nulu. - person Nikola Markovinović; 17.05.2012

Я уверен, что есть какой-то трюк, который вы можете использовать, чтобы сделать все это в одном запросе, но на самом деле это должны быть два отдельных запроса, один для подсчета ADSL, а другой для усреднения не-ADSL. Если вы действительно хотите сделать это за один цикл, вы можете выполнить пару подзапросов, а затем присоединиться к подзапросам в течение месяца. Все это будет намного читабельнее, быстрее, проще в обслуживании, плюс больше канонического SQL.

Кроме того, похоже, что в DB2 есть встроенная функция для возврата названия месяца, ИМЯ МЕСЯЦА: http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000831.html


Что ж, раз уж вы настаиваете... Я не очень хорошо знаком с db2, поэтому синтаксис может немного отличаться, но вы сможете сделать что-то вроде этого:

SELECT avgt.month, countt.data, avgt.data FROM

(SELECT month(timestamp_iso(STATUSDATE)) AS month,count(*) AS data FROM INCIDENT WHERE year(statusdate) = year(current_timestamp) AND service='ADSL' GROUP BY month(timestamp_iso(STATUSDATE))) AS countt

INNER JOIN 

(SELECT month(timestamp_iso(STATUSDATE)) as month,avg(...) AS data FROM INCIDENT WHERE year(statusdate) = year(current_timestamp) AND service!='ADSL' GROUP BY month(timestamp_iso(STATUSDATE))) AS avgt

ON avgt.month=countt.month

Другой способ сделать это может состоять в том, чтобы иметь дело в AVG, которое дает NULL, если service='ADSL'. Из документации AVG не очень ясно, что он делает со значениями NULL, но попробовать стоит.

person Xepo    schedule 16.05.2012
comment
Спасибо за ответ, но мне действительно нужно это в одном запросе. Может быть, вы знаете, как это сделать? Потому что мне нужно отобразить результаты в ОДНОЙ таблице в некоторых ОТЧЕТАХ - person Veljko; 16.05.2012
comment
Это почти правильно, но не совсем так. Текущий результат — 1 апреля; 6.4 0 мая 800 Правильный результат будет 1 апреля; 0 мая 0; Первый столбец 800 - это ADSL, вторая эффективность, но, используя ваш запрос, я получаю пустой результат, потому что они не связаны с ON. из-за 0 значений в эти месяцы. Я полагаю, что это нуждается в небольшой коррекции - person Veljko; 16.05.2012

Рассчитайте AVG оклад, исключая min() и max() оклады в таблице.

select round(avg(table.salary),2) from table
where table.salary NOT IN ((select min(salary) from table), (select max(salary) from table)) 
person KadoJ    schedule 19.10.2019