Autor Zpráva
martymaker01
Profil
Ahoj zdravím všechny.

Potřeboval bych poradit s jedním SQL dotazem, pracuji v nemocnici a zkouším teď vytáhnout data z databáze pacientů.

Databáze je složena z několika tabulek, z nichž každá obsahuje protokol pacitenta (řádek tabulky). Uvedu jen ty ktere potrebuju pro muj dotaz. cislo_pacienta je propojeni mezi jednotlivymi tabulkami aby bylo jasne ktere data pasuji ke kterym. Záznam se stejnym cislem pacienta muze byt v databazi nekolikrat, avsak bude se lisit v datu "protokolu" (řádku)


SP10 - sloupce: cislo_pacienta, SP10datum_protokolu, prijmeni, jmeno, rodne_cislo //zakladni udaje o pacientovi
SP68 - sloupce: cislo_pacienta, SP68datum_protokolu, velikost_implcocky, spoc_parametr, jmeno_cocky //protokol ktery se vypluje pri urcitem druhu operace (katarakta)
SP45 - sloupce: cislo_pacienta, SP45datum_protokolu, sfera, cylindr, osa //vyplnuje se vzdy soucasne s SP68, ale muze byt vyplnen take samostane u pooperacnich vysetreni


Z takovéhoto schématu bych potřeboval vygenerovat tabulku ktera bude mit tyto sloupce:

prijmeni, jmeno, rodne_cislo, velikost_ipmlcocky, 'Datum operace katarakta' (tzn SP68datumprotokolu), sfera (datum rovno datu operace), cylindr (datum rovno datu operace), osa (datum rovno datu operace), sfera (datum mezi +3 a +12 dny od operace katarakta, vysetreni po cca 1 tydnu), cylindr (datum mezi +3 a +12 dny od operace katarakta, vysetreni po cca 1 tydnu), osa (datum mezi +3 a +12 dny od operace katarakta, vysetreni po cca 1 tydnu)

Slovy mi jde o to abych z databaze vytahl informace o vysetreni pacienta v den operace, potom po týdnu (pacienti nechodí přesně po týdnu ale v intervalu +3 až +12 dní od operace), měsíci atd..

Dokážu vytáhnout všechny potřebné údaje v den operace, ale nevím jak k tomu přilepit ještě info o vyšetření po týdnu, měsíci, 3měsících atd.

Dokázal by mi někdo poradit?

Děkuji všem za jakékoliv rady a přeji hezký den.
Zdraví

Martin Šramka
Kajman_
Profil *
martymaker01:
Dokážu vytáhnout všechny potřebné údaje v den operace, ale nevím jak k tomu přilepit ještě info o vyšetření po týdnu, měsíci, 3měsících atd.

Možná to půjde takto nějak
       SP68
left   join SP45
on     SP68.cislo_pacienta = SP45.cislo_pacienta
       and SP68.SP68datum_protokolu = SP45.SP45datum_protokolu -- něco takového tam máte pro den operace což umíte
left   join SP45 as potydnu
on     SP68.cislo_pacienta = potydnu.cislo_pacienta
       and SP68.SP68datum_protokolu+3 <= potydnu.SP45datum_protokolu
       and SP68.SP68datum_protokolu+12 >= potydnu.SP45datum_protokolu
left   join SP45 as pomesici
on     SP68.cislo_pacienta = pomesici.cislo_pacienta
       and SP68.SP68datum_protokolu+13 <= pomesici.SP45datum_protokolu
       and SP68.SP68datum_protokolu+45 >= pomesici.SP45datum_protokolu


Přičítání dnů takto jde jen v některých databázích, některé mají na přičítání dnů speciální funkce.

Pokud v tom rozsahu dnů bude více prohlídek vyplivne to více řádků. Osobně bych se možná nesnažil získat prohlídky z db za sebou jako více sloupců, ale jako více řádků a pouze bych je nějak rozumně zobrazil.
martymaker01
Profil
Moc děkuji za odpověd. V prvním příspěvku jsem se to snažil trošku zestručnit... Dotaz, který používám já pro vytažení potřebných informací v den operace přikládám (je dost mozne ze je v nem chyba, ale data generuje pri kontrole spravne), je tam vložena i část, kterou nevím jak udělat. Mohl bych Vás požádat o modifikaci tohoto dotazu tak aby fungoval i pro vysetreni po tydnu a mesici? Mnohokrate dííík. M.

SELECT
SP68CIS AS 'Číslo pacienta',
SP10PRI AS 'Příjmení',
SP10JME AS 'Jméno',
SP10ROC AS 'Rodné číslo',
SP10POH AS 'Pohlaví - 0:Neuvedeno, 1:Muž, 2:Žena',
SP68DAT AS 'Surgery date',
SP68TDA2 AS 'Calcul. IOL',
SP68DHOD AS 'Implant. IOL',
SP45DNAD AS 'UV',
SP45DVID AS 'Distance BV',
SP45DSFD AS 'SF',
SP45DCYD AS 'CYL',
SP45DAXD AS 'axis',
SP35NTD AS 'IOP',
SP35CCD AS 'CCT',
--a tohle uz nevim jak dal udelat
SP45DNAD AS 'UV', -- po tydnu
SP45DVID AS 'Distance BV', -- po tydnu
SP45DSFD AS 'SF', -- po tydnu
SP45DCYD AS 'CYL', -- po tydnu
SP45DAXD AS 'axis', -- po tydnu
SP35NTD AS 'IOP', -- po tydnu
SP35CCD AS 'CCT',-- po tydnu

SP45DNAD AS 'UV', -- po mesici
SP45DVID AS 'Distance BV', -- po mesici
SP45DSFD AS 'SF', -- po mesici
SP45DCYD AS 'CYL', -- po mesici
SP45DAXD AS 'axis', -- po mesici
SP35NTD AS 'IOP', -- po mesici
SP35CCD AS 'CCT', -- po mesici

SP68IMOD AS 'Typ čočky',
SP60ODG, SP35CCD
FROM SP10, SP45, SP35, SP60, SP68
WHERE SP68.SP68CIS=SP10.SP10CIS
AND SP68.SP68CIS=SP60.SP60CIS
AND (SP68.SP68CIS=SP45.SP45CIS AND SP68DAT=SP45DAT)
AND (SP68.SP68CIS=SP35.SP35CIS AND SP68DAT=SP35DAT)
AND(UCASE(SP60ODG) LIKE UCASE('%tara%od%')) -- filtruji zde, ze se jedna o operaci katarakta
AND UCASE(SP68IMOD) LIKE UCASE('%PDIFF%') -- filtr, ze se pacientu implantuje cocka pdiff
Kajman_
Profil *
Dotaz asi fungovat nebude. Musíte si zjistit, jak se v použité databázi přičítají dny. Možná bude třeba i závorkování v zápisech joinů. Ale pro přibližný nástin řešení to třeba bude stačit.

SELECT SP68CIS       AS 'Číslo pacienta',
       SP10PRI       AS 'Příjmení',
       SP10JME       AS 'Jméno',
       SP10ROC       AS 'Rodné číslo',
       SP10POH       AS 'Pohlaví - 0:Neuvedeno, 1:Muž, 2:Žena',
       SP68DAT       AS 'Surgery date',
       SP68TDA2      AS 'Calcul. IOL',
       SP68DHOD      AS 'Implant. IOL',
       SP45.SP45DNAD AS 'UV',
       SP45.SP45DVID AS 'Distance BV',
       SP45.SP45DSFD AS 'SF',
       SP45.SP45DCYD AS 'CYL',
       SP45.SP45DAXD AS 'axis',
       SP35.SP35NTD  AS 'IOP',
       SP35.SP35CCD  AS 'CCT',
       -- a tohle uz nevim jak dal udelat
       SP45tyden.SP45DNAD AS 'UV t', -- po tydnu
       SP45tyden.SP45DVID AS 'Distance BV t', -- po tydnu
       SP45tyden.SP45DSFD AS 'SF t', -- po tydnu
       SP45tyden.SP45DCYD AS 'CYL t', -- po tydnu
       SP45tyden.SP45DAXD AS 'axis t', -- po tydnu
       SP35tyden.SP35NTD  AS 'IOP t', -- po tydnu
       SP35tyden.SP35CCD  AS 'CCT t', -- po tydnu
       
       SP45mesic.SP45DNAD AS 'UV m', -- po mesici
       SP45mesic.SP45DVID AS 'Distance BV m', -- po mesici
       SP45mesic.SP45DSFD AS 'SF m', -- po mesici
       SP45mesic.SP45DCYD AS 'CYL m', -- po mesici
       SP45mesic.SP45DAXD AS 'axis m', -- po mesici
       SP35mesic.SP35NTD  AS 'IOP m', -- po mesici
       SP35mesic.SP35CCD  AS 'CCT m', -- po mesici
       
       SP68IMOD     AS 'Typ čočky',
       SP60ODG,
       SP35.SP35CCD
FROM   SP10
JOIN   SP68
ON     SP68.SP68CIS = SP10.SP10CIS
JOIN   SP60
ON     SP68.SP68CIS = SP60.SP60CIS
JOIN   SP45
ON     (SP68.SP68CIS = SP45.SP45CIS AND SP68.SP68DAT = SP45.SP45DAT)
JOIN   SP35
ON     (SP68.SP68CIS = SP35.SP35CIS AND SP68.SP68DAT = SP35.SP35DAT)
LEFT   JOIN SP45 AS SP45tyden
ON     (SP68.SP68CIS = SP45tyden.SP45CIS AND
       SP45tyden.SP45DAT >= SP68.SP68DAT + 3 AND
       SP45tyden.SP45DAT <= SP68.SP68DAT + 12)
LEFT   JOIN SP35 AS SP35tyden
ON     (SP68.SP68CIS = SP35tyden.SP35CIS AND
       SP35tyden.SP35DAT >= SP68.SP68DAT + 3 AND
       SP35tyden.SP35DAT <= SP68.SP68DAT + 12)
LEFT   JOIN SP45 AS SP45mesic
ON     (SP68.SP68CIS = SP45mesic.SP45CIS AND
       SP45mesic.SP45DAT >= SP68.SP68DAT + 13 AND
       SP45mesic.SP45DAT <= SP68.SP68DAT + 45)
LEFT   JOIN SP35 AS SP35mesic
ON     (SP68.SP68CIS = SP35mesic.SP35CIS AND
       SP35mesic.SP35DAT >= SP68.SP68DAT + 13 AND
       SP35mesic.SP35DAT <= SP68.SP68DAT + 45)

WHERE  (UCASE(SP60ODG) LIKE UCASE('%tara%od%')) -- filtruji zde, ze se jedna o operaci katarakta
       AND UCASE(SP68IMOD) LIKE UCASE('%PDIFF%') -- filtr, ze se pacientu implantuje cocka pdiff
martymaker01
Profil
Dobrý den, mockrát Vám děkuji za radu. Dotaz funguje, stačilo jen upravit to připočítávání data.
Problém je však v tom, že generování dotazu zabere cca 1 hodinu, a to jsem tam měl vyšetření pouze po týdnu, je možné, že když tam přidám po měsíci tak bude trvat ještě mnohem déle. Nenapadlo by Vás jakým způsobem to zooptimalizovat (je-li to vůbec možné) tak, aby to trvalo kratší dobu, je to vůbec možné? Děkuji Vám mnohokrát opravdu jste mi moc pomohl. Díky M.

Přikládám ještě onen dotaz:

SELECT DISTINCT SP68CIS AS 'Číslo pacienta',
SP10PRI AS 'Příjmení',
SP10JME AS 'Jméno',
SP10ROC AS 'Rodné číslo',
SP10POH AS 'Pohlaví - 0:Neuvedeno, 1:Muž, 2:Žena',
SP68DAT AS 'Surgery date',
SP68TDA2 AS 'Calcul. IOL',
SP68DHOD AS 'Implant. IOL',
SP45.SP45DNAD AS 'UV',
SP45.SP45DVID AS 'Distance BV',
SP45.SP45DSFD AS 'SF',
SP45.SP45DCYD AS 'CYL',
SP45.SP45DAXD AS 'axis',
SP35.SP35NTD AS 'IOP',
SP35.SP35CCD AS 'CCT',
-- a tohle uz nevim jak dal udelat
SP45tyden.SP45DNAD AS 'UV t', -- po tydnu
SP45tyden.SP45DVID AS 'Distance BV t', -- po tydnu
SP45tyden.SP45DSFD AS 'SF t', -- po tydnu
SP45tyden.SP45DCYD AS 'CYL t', -- po tydnu
SP45tyden.SP45DAXD AS 'axis t', -- po tydnu
SP35tyden.SP35NTD AS 'IOP t', -- po tydnu
SP35tyden.SP35CCD AS 'CCT t', -- po tydnu

SP45mesic.SP45DNAD AS 'UV m', -- po mesici
SP45mesic.SP45DVID AS 'Distance BV m', -- po mesici
SP45mesic.SP45DSFD AS 'SF m', -- po mesici
SP45mesic.SP45DCYD AS 'CYL m', -- po mesici
SP45mesic.SP45DAXD AS 'axis m', -- po mesici
SP35mesic.SP35NTD AS 'IOP m', -- po mesici
SP35mesic.SP35CCD AS 'CCT m', -- po mesici

SP68IMOD AS 'Typ čočky',
SP60ODG,
SP35.SP35CCD
FROM SP10
JOIN SP68
ON SP68.SP68CIS = SP10.SP10CIS
JOIN SP60
ON SP68.SP68CIS = SP60.SP60CIS
JOIN SP45
ON (SP68.SP68CIS = SP45.SP45CIS AND SP68.SP68DAT = SP45.SP45DAT)
JOIN SP35
ON (SP68.SP68CIS = SP35.SP35CIS AND SP68.SP68DAT = SP35.SP35DAT)

LEFT JOIN SP45 AS SP45tyden
ON (SP68.SP68CIS = SP45tyden.SP45CIS AND
SP45tyden.SP45DAT >= DATE_ADD(SP68.SP68DAT, INTERVAL 3 DAY) AND
SP45tyden.SP45DAT <= DATE_ADD(SP68.SP68DAT, INTERVAL 15 DAY))
LEFT JOIN SP35 AS SP35tyden
ON (SP68.SP68CIS = SP35tyden.SP35CIS AND
SP35tyden.SP35DAT >= DATE_ADD(SP68.SP68DAT, INTERVAL 3 DAY) AND
SP35tyden.SP35DAT <= DATE_ADD(SP68.SP68DAT, INTERVAL 15 DAY))

LEFT JOIN SP45 AS SP45mesic
ON (SP68.SP68CIS = SP45mesic.SP45CIS AND
SP45mesic.SP45DAT >= DATE_ADD(SP68.SP68DAT, INTERVAL 16 DAY) AND
SP45mesic.SP45DAT <= DATE_ADD(SP68.SP68DAT, INTERVAL 50 DAY))
LEFT JOIN SP35 AS SP35mesic
ON (SP68.SP68CIS = SP35mesic.SP35CIS AND
SP35mesic.SP35DAT >= DATE_ADD(SP68.SP68DAT, INTERVAL 16 DAY) AND
SP35mesic.SP35DAT <= DATE_ADD(SP68.SP68DAT, INTERVAL 50 DAY))

WHERE (UCASE(SP60ODG) LIKE UCASE('%tara%od%')) -- filtruji zde, ze se jedna o operaci katarakta
AND UCASE(SP68IMOD) LIKE UCASE('%PDIFF%')
Kajman_
Profil *
Mají tabulky SP35 a SP45 index na sloupcích SP35CIS resp. SP45CIS?

Pokud v sp35 a sp45 bude po tom týdnu vždy stejné datum, může se zapsat podmínka místo intervalu jako SP35tyden.SP35DAT=SP45tyden.SP45DAT.

Nevím, jak to jinak optimalizovat, co to je za databázi? Mysql? Jaký je výstup při
explain select ...
martymaker01
Profil
Typ databáze je MySQL Server 5.1.24. V SP35 a SP45 stejne datum bude, tak to zjednoduším. Tabulky S35 a SP45 bohužel index na sloupcích SP35 a SP45 bohůžel nemají. Přikládám obrázek explain select. Díky za odpověď.

[img]http://2i.cz/6decb69c4f[/img]
martymaker01
Profil
Radši píši ještě jednou, když tedy v SP35 a SP45 bude stejné datum může se to zjednodušit takto:

LEFT JOIN SP45 AS SP45tyden
ON (SP68.SP68CIS = SP45tyden.SP45CIS AND
SP45tyden.SP45DAT >= DATE_ADD(SP68.SP68DAT, INTERVAL 3 DAY) AND
SP45tyden.SP45DAT <= DATE_ADD(SP68.SP68DAT, INTERVAL 15 DAY))
LEFT JOIN SP35 AS SP35tyden
ON (SP68.SP68CIS = SP35tyden.SP35CIS AND
SP35tyden.SP35DAT=SP45tyden.SP45DAT)


Pochopil jsem to dobře?
Kajman_
Profil *
Ano s tím rovnítkem by to mohlo být možná o chlup rychlejší.

Index by to mohl výrazně zrychlit. Nejvhodnější na tento select by byl složený index na sloupcích (SP35CIS,SP35DAT) v tomhle pořadí a stejně i pro SP45. Ale pro návrh indexů je lepší mít komplexní přehled, co všechno se s tabulkou dělá a jak často.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: