Diskuze: MS-SQL-Server, Where podmienka,
V předchozím kvízu, Online test znalostí SQL a databází, jsme si ověřili nabyté zkušenosti z kurzu.


Myslim ze je to spatne ve vysledku budes mit lidi kteri uzivali jakykoliv lek (vybrany)
SELECT DISTINCT X.PatientDim AS ID_patient,
A.code AS codeA,
A.description, AS descriptionA,
B.code AS codeB,
B.description AS descriptionB
FROM data_star.dbo.F_drugconsumption X
INNER JOIN dbo.D_drug A ON X.DrugDim = A.id AND A.ATC7_code LIKE 'A10B%'
INNER JOIN dbo.D_drug B ON X.DrugDim = B.id AND B.ATC7_code LIKE 'C10%'
WHERE (X.DateDim >='20200101' )
AND ( X.DateDim <='20201231' ) --pri datetime '20201231 23:25:59' nebo <'20210101'
AND ( X.AgeDim <='125' ) --?
Muze to vypsat jednoho cloveka vicekrat pokud pouzival vice druhu leku A10Bx,A10By
Milan Trnovec:12.4.2022 13:15
dakujem, skusil som to presne podla tvojho navodu, ale nefunguje to. Ked v Selecte pridam aliasy k drug.code vypise mi " The multi-part identifier "dbo.D_Liek.KOD" could not be bound". To iste vypise aj pri pridani aliasu ku drugdescription. Pri tom v mojom Selecte to normalne ide.
Petan:12.4.2022 13:35
Kdyz tak misto dbo.D_Liek. tam musi byt A. nebo B.
Co nefunguje na mem prikladu, jakou to vraci chybu?
Kdyz si nejsi jisty vysledkem, tak si ho vypis ne? A postupne doledej v
databazi.
Ja si nejsem jisty uplne tim kodem, co tam mas. Ty si tam nejak nahodile
pridavas prefixy a podivne to grupujes. Proc to grupujes podle drug-code? A
borec pres db je tu Petan Ale,
zkusim tu jeho verzi a tvoji nejak spojit
SELECT DISTINCT
X.PatientDim AS ID_patient,
A.code AS codeA,
A.description, AS descriptionA,
FROM
data_star.dbo.F_drugconsumption X
LEFT JOIN dbo.D_drug A ON X.DrugDim = A.id
WHERE
(A.ATC7_code LIKE 'A10B%' OR A.ATC7_code LIKE 'C10%')
AND (X.DateDim >='20200101' ) -- ty podminky s casem neresim
AND (X.DateDim <='20201231' )
AND (X.AgeDim <='125' )
GROUP BY
X.PatientDim
HAVING
COUNT (dbo.D_drug.ATC7_code) >= 2
-- ,X.D_drug.code -- proc to grupujes podle code, kdyz code by asi melo byt unikatni, odlisne pro
-- A.ATC7_code LIKE 'A10B%' OR A.ATC7_code LIKE 'C10%'
-- ,X.description -- a proc to grupujes podle description, kdyz code je unikatni
A ono se mi tam nezda vic veci.
Kdyz pacient bude v danem obdobi uzivate lek opakovane, tak grup podle mne i
podle tebe poscita vsechny radky, kterych muze byt treba 5. Ale, mozna se pletu,
ja moc grupovani nemusim
lek = 1, pacient = 1, cas = 10
lek = 1, pacient = 1, cas = 20
count group == 2
lek = 1, pacient = 1, cas = 10
lek = 1, pacient = 1, cas = 20
lek = 1, pacient = 1, cas = 30
count group == 3
lek = 1, pacient = 1, cas = 10
lek = 1, pacient = 1, cas = 20
lek = 2, pacient = 1, cas = 30
count group == 3
Cili, podle mne bys mel vybrat kazda data zvlast, pak je spojit. A pak porovnavat group==2
SELECT
pacient-id
lek-id
(
SELECT
pacient-id
lek-id
WHERE
lek-code like 'kod1' OR lek-code like 'kod2'
GROUP BY
pacient-id
lek-id
)
GROUP BY
pacient-id
HAVING
COUNT (pacient-id) == 2
V prvni fazi ziskas 1 radek pro lek 1 a jeden radek pro lek 2. V druhe fazi
oba radky spojis podle pacienta.
Ale, mozna to jde zgrupovat nejak najednou, nevim. Nebo, mozna by stacil maly
zasah do toho kodu od Petan, ale na to si moc netroufam. Ja bych to resil spis
takto, protoze, pak vim, co bude vysledkem.
Milan Trnovec:20.4.2022 12:29
ahoj, ospravedlnujem sa, zle som to prepisal. Vyzera to celkom nadejne, akurat ako results mi vyhodí len hlavicky sltpcov (columns) bez riadkov (rows).
SELECT dbo.F_SpotrebaLiekov.PacientDim AS ID_patient,
A.KOD AS codeA,
A.POP AS descriptionA,
B.KOD AS codeB,
B.POP AS descriptionB,
SUM(dbo.F_SpotrebaLiekov.Mnozstvo) AS Mnozstvo
FROM datazp_star.dbo.F_SpotrebaLiekov
inner JOIN dbo.D_Liek A ON dbo.F_SpotrebaLiekov.LiekDim = A.id AND A.ATC7_KOD like 'A10B%'
inner JOIN dbo.D_Liek B ON dbo.F_SpotrebaLiekov.LiekDim = B.id AND B.ATC7_KOD like 'C10%'
WHERE (dbo.F_SpotrebaLiekov.DatumRealizacieDim >='20200101' )
AND ( dbo.F_SpotrebaLiekov.DatumRealizacieDim<='20201231' )
AND ( dbo.F_SpotrebaLiekov.VekDim<='125' )
group by dbo.F_SpotrebaLiekov.PacientDim,
A.KOD,
A.POP,
B.KOD,
B.POP,
dbo.F_SpotrebaLiekov.Mnozstvo
Po odpalení Execute mi vyhodi len toto, teda len hlavicky sltpcov.
id_patient | codeA | descriptionA | codeB | descriptionB | Mnozstvo |
---|
Skusil som poskusat rozne variacie inner join/left/right/full join ale nic
nefunguje tak ako by som chcel,
napr. ked dam inner join a left join, tak sa to uz dost podoba tomu ako by som
chcel aby to vyzeralo, akurat mi tam vyhadzuje NULL hodnoty.
id_patient | codeA | descriptionA | codeB | descriptionB | Mnozstvo |
---|---|---|---|---|---|
5896486 | C79528 | Galvus tbl. 30x50mg | NULL | NULL | 5.000 |
Mojim cielom je aby to vyzeralo nasledovne, GROUP BY som tam dal preto, lebo potrebujem spocitat (SUM) celkove mnozstvo lieku A a sucasne lieku B, ktore uzival konkretny pacient za 1 rok.
id_patient | codeA | descriptionA | codeB | descriptionB | Mnozstvo |
---|---|---|---|---|---|
1256489 | C89578 | METFORMIN 40X50mg | C12569 | SIOFOR 1000mg | 15.000 |
Vyhoď z group by dbo.F_SpotrebaLiekov.Mnozstvo
Máš tam skutečně pacienta kterz bere kombinaci ? (v pozadovanem obdobi a
VekDim<='125')
Zkontroluj si podminku ATC7_KOD like 'A10B%' a ATC7_KOD like 'C10%'
Je v tabulce dbo.D_Liek idPacienta jako id?
Petan:20.4.2022 13:58
Posledni ? ma byt F_SpotrebaLiekov.LiekDim = id v tabulce D_Liek.?
Petan:20.4.2022 14:07
Postupuj asi takto
1 vyzkosej
SELECT dbo.F_SpotrebaLiekov.PacientDim AS ID_patient,
A.KOD AS codeA,
A.POP AS descriptionA,
B.KOD AS codeB,
B.POP AS descriptionB
FROM datazp_star.dbo.F_SpotrebaLiekov
inner JOIN dbo.D_Liek A ON dbo.F_SpotrebaLiekov.LiekDim = A.id AND A.ATC7_KOD like 'A10B%'
inner JOIN dbo.D_Liek B ON dbo.F_SpotrebaLiekov.LiekDim = B.id AND B.ATC7_KOD like 'C10%'
pokud ti to neco vraci tak pridavej podminky WHERE
2.
WHERE (dbo.F_SpotrebaLiekov.DatumRealizacieDim >='20200101' )
3.
AND ( dbo.F_SpotrebaLiekov.DatumRealizacieDim<='20201231' )
4.
AND ( dbo.F_SpotrebaLiekov.VekDim<='125' )
a potom pridej sumaci
5.
SUM(dbo.F_SpotrebaLiekov.Mnozstvo) AS Mnozstvo
a
GROUP BY dbo.F_SpotrebaLiekov.PacientDim,
A.KOD,
A.POP,
B.KOD,
B.POP
Milan Trnovec:20.4.2022 14:20
vyhodil som, ano mal by tam byt pacient len za obdobie od zaciatku roku
'20200101' po' 20201231', ta podmienka s vekom tam je preto, lebo su tam aj
hodnoty, ktore mi vyhadzuju pacientov kt. maju 250rokov, co je obviously
blbost.
podmienka by mala byt ok,
V tabulke dbo.D_Liek nie je id pacienta, je tam sice stlpec id, ale je to len
ciselne poradie (tj. 1,2,3,4,5,6...). Takze problem bude asi tu,
Je mozne to nejako prepojit cez ten KOD lieku?
ID_pacienta mam len v tej dimenzii dbo.F_SpotrebaLiekov ako PacientDim a
vlastne ta tabulka dbo.D_Liek je sucast tej dimenzie.
Petan:20.4.2022 14:44
Promin ode mne vse spatne
moc jsem nad tim nepremyslel
melo by to byt neco ve stylu
SELECT
A.PacientDim,
A.KOD AS KodA,
A.POP AS PopA,
B.KOD AS KodB,
B.POP AS PopB,
SUM(A.Mnozstvo) + SUM(B.Mnozstvo) AS Mnozstvo
FROM
(SELECT S.PacientDim,S.Mnozstvo,S.DatumRealizacieDim,L.KOD,L.POP,S.VekDim
FROM dbo.F_SpotrebaLiekov S inner JOIN dbo.D_Liek L ON S.LiekDim = L.id AND L.ATC7_KOD like 'A10B%') A
(SELECT S.PacientDim,S.Mnozstvo,S.DatumRealizacieDim,L.KOD,L.POP,S.VekDim
FROM dbo.F_SpotrebaLiekov S inner JOIN dbo.D_Liek L ON S.LiekDim = A.id AND L.ATC7_KOD like 'C10%') B
ON A.PacientDim = B.PacientDim
WHERE
A.DatumRealizacieDim >='20200101' )
AND A.DatumRealizacieDim <='20201231' )
B.DatumRealizacieDim >='20200101' )
AND B.DatumRealizacieDim <='20201231' )
AND ( A.VekDim<='125' )
AND ( B.VekDim<='125' )
GROUP BY
A.PacientDim,
A.KOD AS KodA,
A.POP AS PopA,
B.KOD AS KodB,
B.POP AS PopB,
Vytvori se dve virtualni tabulky (muzou byt View) spojenim F_SpotrebaLiekov a
D_Liek s podminkou druhu leku viz like
a nasledne spojit tyto tabulky pres idPacienta
tak snad
edit: pridal som k povodnemu zadaniu
INNER jOIN dbo.D_Pacient ON dbo.F_SpotrebaLiekov.PacientDim = dbo.D_Pacient.Id
ale zas mi vyhadzuje len hlavicky slpcov, bez rows, skusal som aj rozne kombinacie joinov(LEFT/RIGHT/FULL) ale zas ako predtym vyhadzuje NULL hodnoty.
edit2: skusal som to aj po jednom pridavat, ako si napisal pred chvilou, ale bez uspechu, stale vyhadzuje len hlavicky sltpcov bez rows
Petan:20.4.2022 14:56
To co jsem psal predtim je spatne ! . vyzkousej to moje z 14:44 s dvema virtualnimi tabulkamy spojene INNER JOIN doufam ze jsem tam neudelal moc chyb, kdyz tak potom bych si to skusil nasimulovat, pisu to jen tak z hlavy
Tech chyb tam je ted asi vic.
- AS KodA, atd tam nema byt
- B.POP AS PopB, tady carka na konci
- U toho From si nejsem uplne jisty zapisem, zda mezi (select...) a a (select...) b nema byt carka nebo UNION
- u where schazi nejaky AND a jsou tam zbytecne zavorky navic (ale ty nicemu nevadi)
- a mozna jeste neco
SELECT a.pacientdim,
a.kod AS koda,
a.pop AS popa,
b.kod AS kodb,
b.pop AS popb,
Sum(a.mnozstvo) + Sum(b.mnozstvo) AS mnozstvo
FROM (
SELECT
s.pacientdim,
s.mnozstvo,
s.datumrealizaciedim,
l.kod,
l.pop,
s.vekdim
FROM dbo.f_spotrebaliekov S
INNER JOIN dbo.d_liek L ON s.liekdim = l.id AND l.atc7_kod LIKE 'A10B%'
) a,
(
SELECT
s.pacientdim,
s.mnozstvo,
s.datumrealizaciedim,
l.kod,
l.pop,
s.vekdim
FROM dbo.f_spotrebaliekov s
INNER JOIN dbo.d_liek l ON s.liekdim = a.id AND l.atc7_kod LIKE 'C10%'
) b
-- ??? ON a.pacientdim = b.pacientdim
WHERE
a.datumrealizaciedim >='20200101' AND a.datumrealizaciedim <='20201231'
AND b.datumrealizaciedim >='20200101' AND b.datumrealizaciedim <='20201231'
AND a.vekdim<='125'
AND b.vekdim<='125'
GROUP BY
a.pacientdim, --- tady si nejsem jisty, zda se to da podle toho dim grupovat, spis neuvadet zadny prefix "a." ani "b."
a.kod,
a.pop,
b.kod,
b.pop
A sorry, ten formatovac mi to divne rozhazel s mezerami, neco jsem spravil,
na neco sem se vybodl
No nedalo mi to, vygeneroval jsem obrovske mnozstvi chyb
tak jsem to musel otestovat
vytvoril jsem si dve tabulky a naplnil testovacimi daty
CREATE TABLE F_SpotrebaLiekov(PacientDim int,LiekDim int,Mnozstvo int,DatumRealizacieDim date,VekDim varchar(10));
CREATE TABLE D_Liek(id int,KOD varchar(20),POP varchar(20),ATC7_KOD varchar(20));
INSERT INTO D_Liek(id,KOD,POP,ATC7_KOD)VALUES(1,'TEST1','Test1','A15XXX');
INSERT INTO D_Liek(id,KOD,POP,ATC7_KOD)VALUES(2,'TEST2','Test2','A15XYZ');
INSERT INTO D_Liek(id,KOD,POP,ATC7_KOD)VALUES(3,'TEST3','Test3','A10BCD');
INSERT INTO D_Liek(id,KOD,POP,ATC7_KOD)VALUES(4,'TEST4','Test4','C10ZZZ');
INSERT INTO F_SpotrebaLiekov(PacientDim,LiekDim,Mnozstvo,DatumRealizacieDim,VekDim)VALUES(1,1,10,'20200202','') ;
INSERT INTO F_SpotrebaLiekov(PacientDim,LiekDim,Mnozstvo,DatumRealizacieDim,VekDim)VALUES(2,3,5,'20200202','') ;
--sloucit tyto dva
INSERT INTO F_SpotrebaLiekov(PacientDim,LiekDim,Mnozstvo,DatumRealizacieDim,VekDim)VALUES(3,3,3,'20200202','') ; --p3
INSERT INTO F_SpotrebaLiekov(PacientDim,LiekDim,Mnozstvo,DatumRealizacieDim,VekDim)VALUES(3,4,4,'20200202','') ; --p3
INSERT INTO F_SpotrebaLiekov(PacientDim,LiekDim,Mnozstvo,DatumRealizacieDim,VekDim)VALUES(4,2,10,'20200202','') ;
--Sloucit tyto 3
INSERT INTO F_SpotrebaLiekov(PacientDim,LiekDim,Mnozstvo,DatumRealizacieDim,VekDim)VALUES(5,4,2,'20200202','') ; --P5
INSERT INTO F_SpotrebaLiekov(PacientDim,LiekDim,Mnozstvo,DatumRealizacieDim,VekDim)VALUES(5,3,2,'20200202','') ; --P5
INSERT INTO F_SpotrebaLiekov(PacientDim,LiekDim,Mnozstvo,DatumRealizacieDim,VekDim)VALUES(5,3,2,'20200802','') ; --P5
tady toto je funkcni dotaz v jednom selectu jinak je to spise na proceduru
SELECT
A.PacientDim,
A.KOD AS KodA,
A.POP AS PopA,
B.KOD AS KodB,
B.POP AS PopB,
A.Mnozstvo AS MnozstvoA,
B.Mnozstvo AS MnozstvoB,
A.Mnozstvo + B.Mnozstvo AS MnozstvoCelkom
FROM
(SELECT S.PacientDim,L.KOD,L.POP,SUM(S.Mnozstvo) AS Mnozstvo
FROM F_SpotrebaLiekov S inner JOIN D_Liek L ON S.LiekDim = L.id
WHERE (L.ATC7_KOD like 'A10B%') AND (S.DatumRealizacieDim >='20200101') AND (S.DatumRealizacieDim <='20201231') AND (S.VekDim<='125')
GROUP BY S.PacientDim,L.KOD,L.POP) A
INNER JOIN
(SELECT S.PacientDim,L.KOD,L.POP,SUM(S.Mnozstvo) AS Mnozstvo
FROM F_SpotrebaLiekov S inner JOIN D_Liek L ON S.LiekDim = L.id
WHERE (L.ATC7_KOD like 'C10%') AND (S.DatumRealizacieDim >='20200101') AND (S.DatumRealizacieDim <='20201231') AND (S.VekDim<='125')
GROUP BY S.PacientDim,L.KOD,L.POP) B
ON A.PacientDim = B.PacientDim
ty sumace musi byt v tech podselectech
snad uz to bude OK
Petan:20.4.2022 20:51
super pohledem jsi odhalil spoustu chyb, ktere jsem si nevsiml (a zbezne jsem
si to kontroloval !)
AS KodA, atd tam nema byt --ano v GROUP BY to nemuze byt kopiroval jsem to z
casti SELECT
B.POP AS PopB, tady carka na konci --Jo jo pisu a nejak jsem si to nevsimnul
U toho From si nejsem uplne jisty zapisem, zda mezi (select...) a a (select...)
b nema byt carka nebo UNION --Ma tam byt INNER JOIN
u where schazi nejaky AND a jsou tam zbytecne zavorky navic (ale ty nicemu
nevadi) --pravda i AND mi vypadlo taky, zavorky tam byt nemusi ale toto, ze je
tam jenom cast by vyhodil prekladac neco ve stylu naer ")" syntax
error
a mozna jeste neco --a jeste by to spatne pocitalo nnozstvi v pripade vice
odebraneho druhu leku v danem obdobi
Dobry, neres. To je tim, ze to pises z hlavy. Takovych prispevku tu mam jinde
spousty
Zobrazeno 18 zpráv z 18.