IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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.

Aktivity
Avatar
Milan Trnovec:11.4.2022 23:09

Ahojte, mam zadanie tykajuce sa vyberu liekov, potrebujem vybrat vsetkych ludi (id_pacientov) za urcity rok, ktory uzivali liek A a sucasne s nim aj liek B. Nechcem mat vo vysledku ludi (id_pacientov), ktori uzivali len liek A alebo len liek B.

Zkusil jsem:

SELECT   dbo.drugconsumption.PatientDim AS ID_patient,
       dbo.drug.code,
       dbo.drug.description

FROM   data_star.dbo.F_drugconsumption
            LEFT JOIN dbo.D_drug ON DrugDim = dbo.D_drug.id

WHERE ( dbo.D_drug.ATC7_code LIKE 'A10B%'
        OR
        dbo.D_drug.ATC7_code LIKE 'C10%'
      )
AND  ( dbo.F_drugconsumption.DateDim >='20200101' )
AND  ( dbo.F_drugconsumption.DateDim <='20201231' )
AND  ( dbo.F_drugconsumption.AgeDim <='125' )

GROUP BY
      dbo.F_drugconsumption.PatientDim,
      dbo.D_drug.code,
      dbo.D_drug.description

HAVING  COUNT (dbo.D_drug.ATC7_code) = 2

Chci docílit: Vysledok som dostal aj takto, pomocou tohto dopytu. Lenze problem je v tom, ze som si nie isty, ci SQL podla tohto mojho dopytu vybralo len ludi, ktori uzivali sucasne liek A aj liek B alebo su tam aj ludia, ktori uzivali bud len liek A alebo len liek B ( tychto tam nechcem mat)
Dakujem za pomoc, M.

 
Odpovědět
11.4.2022 23:09
Avatar
Petan
Člen
Avatar
Petan:12.4.2022 7:15

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

 
Nahoru Odpovědět
12.4.2022 7:15
Avatar
Odpovídá na Petan
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.

 
Nahoru Odpovědět
12.4.2022 13:15
Avatar
Petan
Člen
Avatar
Odpovídá na Milan Trnovec
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?

 
Nahoru Odpovědět
12.4.2022 13:35
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:12.4.2022 15:39

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.

 
Nahoru Odpovědět
12.4.2022 15:39
Avatar
Odpovídá na Petan
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/rig­ht/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
 
Nahoru Odpovědět
20.4.2022 12:29
Avatar
Petan
Člen
Avatar
Petan:20.4.2022 13:52

Vyhoď z group by dbo.F_Spotreba­Liekov.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?

 
Nahoru Odpovědět
20.4.2022 13:52
Avatar
Petan
Člen
Avatar
Odpovídá na Petan
Petan:20.4.2022 13:58

Posledni ? ma byt F_SpotrebaLie­kov.LiekDim = id v tabulce D_Liek.?

 
Nahoru Odpovědět
20.4.2022 13:58
Avatar
Petan
Člen
Avatar
Odpovídá na Milan Trnovec
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
 
Nahoru Odpovědět
20.4.2022 14:07
Avatar
Odpovídá na Petan
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_Spotreba­Liekov ako PacientDim a vlastne ta tabulka dbo.D_Liek je sucast tej dimenzie.

 
Nahoru Odpovědět
20.4.2022 14:20
Avatar
Petan
Člen
Avatar
Odpovídá na Milan Trnovec
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

 
Nahoru Odpovědět
20.4.2022 14:44
Avatar
Milan Trnovec:20.4.2022 14:46

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/RIG­HT/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

 
Nahoru Odpovědět
20.4.2022 14:46
Avatar
Petan
Člen
Avatar
Odpovídá na Milan Trnovec
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

 
Nahoru Odpovědět
20.4.2022 14:56
Avatar
Petan
Člen
Avatar
Odpovídá na Petan
Petan:20.4.2022 14:57

A jeste se divam v GROUP BY nema byt AS..

 
Nahoru Odpovědět
20.4.2022 14:57
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:20.4.2022 15:50

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 :)

Editováno 20.4.2022 15:51
 
Nahoru Odpovědět
20.4.2022 15:50
Avatar
Petan
Člen
Avatar
Petan:20.4.2022 20:27

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

 
Nahoru Odpovědět
20.4.2022 20:27
Avatar
Petan
Člen
Avatar
Odpovídá na Peter Mlich
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

 
Nahoru Odpovědět
20.4.2022 20:51
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:21.4.2022 8:36

Dobry, neres. To je tim, ze to pises z hlavy. Takovych prispevku tu mam jinde spousty :)

 
Nahoru Odpovědět
21.4.2022 8:36
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 18 zpráv z 18.