sas sum case when

0

Cześć, uczę się sasa. Napotkałem na problem przy zadaniu. Próbowałem już na wiele innych sposobów z countami, sumami, caseami. Chcę uzyskać 2 kolumny po 3 rekordy podział pracowników na zawody oraz ich odsetek w firmie:

PRACOWNIK_TYPE WYNIK

IT 0,20
MECHANIK 0,45
KIEROWCA 0,35

Co otrzymuję:

PRACOWNIK_TYPE WYNIK

IT 1
MECHANIK 1
KIEROWCA 1
IT 1
MECHANIK 1
KIEROWCA 1
MECHANIK 1
KIEROWCA 1
MECHANIK 1
KIEROWCA 1
IT 1
IT 1

Nie rozumiem co jest nie tak?


```PROC SQL;

CREATE TABLE tabela.pracownicy AS

SELECT

CASE WHEN PRACOWNIK_TYPE='It' THEN "It"
WHEN PRACOWNIK_TYPE='Mechanik' THEN "Mechanik"
WHEN PRACOWNIK_TYPE='Kierowca' THEN "Kierowca"
END AS PRACOWNIK_TYPE,

CASE WHEN IS_IT_FLG=1 THEN SUM(IS_IT_FLG)/COUNT(PRACOWNIK_ID) 
WHEN IS_MECHANIK_FLG=1 THEN SUM(IS_MECHANIK_FLG)/COUNT(PRACOWNIK_ID)
WHEN IS_KIEROWCA_FLG=1 THEN SUM(IS_KIEROWCA_FLG)/COUNT(PRACOWNIK_ID)
END AS WYNIK
 
FROM A.ID_PRACOWNIKOW np
JOIN B.FLAGI f ON np.IDP=f.iIDP
JOIN C.CZAS c ON np.CZASID=c.CZASID

/*WHERE DAY_DT='2019-03-31'*/

;QUIT;
1

Po pierwsze i najważniejsze nie grupujesz to jak możesz dostać 3 rekordy a nie tyle ile jest w tabeli A.ID_PRACOWNIKOW (spełniające inne warunki).

Po 2 taki CASE Ci nie zadziała bo przeciez wtedy sumujesz tylko ten konkretny rekord jak już byś chciał tak to musiał byś to zrobić coś ala:

CASE WHEN IS_IT_FLG=1 THEN  (SELECT SUM(IS_IT_FLG) FROM ...  ) / (SELECT COUNT(PRACOWNIK_ID) FROM .... 

Gdzie we FROM podajesz odpowiednie tabele. Ale generalnie ja bym to raczej zrobił z pomocnicza CTE - żeby bylo czytelniej.

0

GROUP BY się nie wkleiło.
Zróbmy dla jednego typu pracownika. Mam jeszcze nieugruntowaną wiedzę. Czy teraz muszę w podzapytaniach joinować te tabele od początku?


```CREATE TABLE tabela.pracownicy AS

SELECT

CASE WHEN PRACOWNIK_TYPE='It' THEN "It"
/*WHEN PRACOWNIK_TYPE='Mechanik' THEN "Mechanik"*/
/*WHEN PRACOWNIK_TYPE='Kierowca' THEN "Kierowca"*/
END AS PRACOWNIK_TYPE,

CASE WHEN IS_IT_FLG=1 THEN  (SELECT SUM(IS_IT_FLG) FROM B.FLAGI) / (SELECT COUNT(PRACOWNIK_ID) FROM A.ID_PRACOWNIKÓW)
/*WHEN IS_MECHANIK_FLG=1 THEN SUM(IS_MECHANIK_FLG)/COUNT(PRACOWNIK_ID)*/
/*WHEN IS_KIEROWCA_FLG=1 THEN SUM(IS_KIEROWCA_FLG)/COUNT(PRACOWNIK_ID)*/
END AS WYNIK

FROM A.ID_PRACOWNIKOW np
JOIN B.FLAGI f ON np.IDP=f.iIDP
JOIN C.CZAS c ON np.CZASID=c.CZASID

GROUP BY 1

/*WHERE DAY_DT='2019-03-31'*/

;QUIT;
1

Trochę się idzie tu u Ciebie pogubić. Pierwszy CASE jest bez sensu w ogóle:

CASE WHEN PRACOWNIK_TYPE='It' THEN "It"
/*WHEN PRACOWNIK_TYPE='Mechanik' THEN "Mechanik"*/
/*WHEN PRACOWNIK_TYPE='Kierowca' THEN "Kierowca"*/
END AS PRACOWNIK_TYPE,

To nic nie daje jakbyś zostawił po prostu PRACOWNIK_TYPE i Grupował po tej kolumnie to dostaniesz ten sam efekt. No i teraz faktycznie powinieneś mieć dobre wyniki (o ile dobrze czytam Twoja strukturę danych). Sprawdzałeś w ogóle jaki wynik daje Ci to zapytanie?

0

W ogóle się nie kompiluje wyrzuca error z błędną składnią. Podkreśla pierwszego z ostatnich FROMów gdzie je JOINuje.

1

Wykonaj ten kod i sprawdź czy działa:

SELECT

 PRACOWNIK_TYPE,

CASE WHEN IS_IT_FLG=1 THEN  (SELECT SUM(IS_IT_FLG) FROM B.FLAGI) / (SELECT COUNT(PRACOWNIK_ID) FROM A.ID_PRACOWNIKÓW)
/*WHEN IS_MECHANIK_FLG=1 THEN SUM(IS_MECHANIK_FLG)/COUNT(PRACOWNIK_ID)*/
/*WHEN IS_KIEROWCA_FLG=1 THEN SUM(IS_KIEROWCA_FLG)/COUNT(PRACOWNIK_ID)*/
END AS WYNIK

FROM A.ID_PRACOWNIKOW np
JOIN B.FLAGI f ON np.IDP=f.iIDP
JOIN C.CZAS c ON np.CZASID=c.CZASID

GROUP BY PRACOWNIK_TYPE
0

Wszystko się skompilowało, ale działam na potężnej bazie i zapytanie zostało przed chwilą ubite przez administratora..

0

Doszedłem już jak to zgrupować, ale teraz nie wiem jak wyliczyć z tego procent w takim case. Wychodzi dla wszystkich przypadków 1 zamiast liczby<1. Wiem dlaczego tak się dzieję, ale nie wiem jak psotawić warunek, żeby pracownik_id zliczał nie tylko np dla "It", ale dla wszystkich.


```CASE WHEN PRACOWNIK_TYPE='IT' THEN COUNT(PRACOWNIK_TYPE)/COUNT(PRACOWNIK_ID)
WHEN PRACOWNIK_TYPE='Mechanik' THEN COUNT(PRACOWNIK_TYPE)/COUNT(PRACOWNIK_ID)
WHEN PRACOWNIK_TYPE='Kierowca' THEN COUNT(PRACOWNIK_TYPE)/COUNT(PRACOWNIK_ID)
END AS WYNIK
1

Ciągle nie kumasz zasady ... tutaj dalej liczysz wszystkie typy pracowników a nie tylko IT.

CASE WHEN PRACOWNIK_TYPE='IT' THEN COUNT(PRACOWNIK_TYPE)/COUNT(PRACOWNIK_ID)

Innymi słowy sprawdzasz warunek czy Pracownik IT jak tak to wykonaj działanie .. i robisz dokładnie to samo działanie dla każdego typu pracownika ... no to logiczne, że zawsze dostaniesz ten sam wynik.

Mówię Ci zrób sobie pomocniczą tabele:

WITH licznikZawodow
as
( SELECT PRACOWNIK_TYPE, COUNT(PRACOWNIK_TYPE) licznikPrac
FROM TwojaTabela
GROUB BY PRACOWNIK_TYPE)

I później w twoim ostatecznym SELECT podłącz sobie tą tablice licznikZawodow po polu Pracownik TYPE i robisz zwykłe działanie

SELECT PRACOWNIK_TYPE, licznikZawodow.licznikPrac / COUNT(PRACOWNIK_ID) as Wynik
FROM ....

0

Jeżeli dobrze rozumiem intencje pytającego, to można tak (nie mam SAS by przetestować)

Select
    PRACOWNIK_TYPE
    ,ILP/ILALL
FROM
    (SELECT
	   PRACOWNIK_TYPE,
	   COUNT(PRACOWNIK_ID) ILP
    FROM 
	   A.ID_PRACOWNIKOW np
	   JOIN B.FLAGI f ON np.IDP=f.iIDP
	   JOIN C.CZAS c ON np.CZASID=c.CZASID
	GROUP BY
	   PRACOWNIK_TYPE
	) P
    CROSS JOIN (SELECT
	   			COUNT(*) ILALL
			 FROM 
				A.ID_PRACOWNIKOW np
				JOIN B.FLAGI f ON np.IDP=f.iIDP
				JOIN C.CZAS c ON np.CZASID=c.CZASID
	) AL

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