Kod polecenia średniej długości zatrudnienia

0

Cześć,

Czy byłby ktoś w stanie wyjaśnić dlaczego po uruchomieniu danego kodu otrzymuje wartość NULL i co zmienić żeby otrzymać poprawny wynik:

SELECT
round(avg(datediff(termdate, hire_date))/365,0) AS avg_length_employment
FROM hr
WHERE termdate <= curdate() AND (termdate IS NULL OR termdate > CURDATE()) AND age >= 18;

0

A jaki jest poprawny wynik? O zależy od danych których tu nie widać

0

A warunek w ogóle zwraca jakieś dane?

5

Jak przeanalizujesz swój warunek

termdate <= curdate() AND (termdate IS NULL OR termdate > CURDATE())

To właściwie możesz zapisać jako

Termdate is null

Ponieważ konikcja warunku

termdate <= curdate() AND termdate > CURDATE()

Nigdy nie będzie prawdziwa, czyli w termdate masz nulla, a jak sprawdzisz dokumentację datediff to dowiesz się że że jeżeli wstawisz nulla jako argument to dostaniesz nulla jako wynik.

Średnia z null to null, dlatego masz w wyniku nulla

UPDATE:

Zrobiłem błąd logiczny

Warunek

termdate <= curdate()

Sprawia, że wyklucza rekordy z nullem w termdate, czyli alternatywa z is null nie ma sensu, bo zostaje koniunkcja

termdate <= curdate() AND termdate > CURDATE()

Która nie przyjmie nigdy prawdy w wyniku więc wynik będzie pusty => AVG da nulla

1
Nati24 napisał(a):

Cześć,

Czy byłby ktoś w stanie wyjaśnić dlaczego po uruchomieniu danego kodu otrzymuje wartość NULL i co zmienić żeby otrzymać poprawny wynik:

SELECT
round(avg(datediff(termdate, hire_date))/365,0) AS avg_length_employment
FROM hr
WHERE termdate <= curdate() AND (termdate IS NULL OR termdate > CURDATE()) AND age >= 18;

Kolega @Panczo wyjaśnił elegancko skąd NULL.

Ja dodałbym, żebyś przemyślał jeszcze logikę.
Jeśli liczysz dla wszystkich to masz takie sytuacje:

i) termdate jest bo kiedyś nastąpiło zwolnienie - tak więc prosto możesz AVG policzyć
ii) termdate jest ale dopiero w przyszłości - nie możesz policzyć AVG wprost, bo wyjdzie przekłamany wynik - więc dla tego przypadku będzie termdate to po prostu curdate (bieżąca)
iii) termdate nie ma bo umowa na czas nieokreślony - nie możesz policzyć ABG wprost bo wyjdzie bzdura - więc dla tego przypadku termdate to po prostu curdate(bieżąca)

wydaje mi się że powinien zadziałać case coś mniej więcej tak:

SET termdate = 
    (CASE 
    WHEN ((termdate <= curdate) THEN termdate --(i)
    WHEN ((termdate > curdate) THEN curdate --(ii)
    ELSE curdate --(iii)
       END)

1 użytkowników online, w tym zalogowanych: 0, gości: 1