Vajíčková mánie Vajíčková mánie
Od 15. do 21.4. slevy 20 až 80% v sekci C/C++. Když ne teď, tak kdy?
Vyšlehej si extra vědomosti! Až 100% bodů na prémiový obsah zdarma! Více zde

Diskuze: Knižnica PostgreSQL - Ako riešiť duplicitne knihy

Aktivity (1)
Avatar
Patrik Živčák:2. ledna 16:12

Rozmýšlanie.

Zkusil jsem: Napadlo ma buď dať pri vytváraní tabuľky nejaký int počet_kníh s defaultom na 1 alebo vytvoriť samostatnú asi sa to vola väzobnú tabuľku kde by bolo id_knihy a potom počet_kópii mňa hlavne štve ako sa to potom pri selecte zobrazí lebo mali by to byt dve samostatne knihy, ktoré sa dajú neskor požičať. No, ale keby som zadal potom pri pridávaní knihy, že počet kópii = 10 000 tak asi tiež by to nebolo úplne dobre, ak by mi vytvorilo 10 000 záznamov rovnakej knihy priamo v DB tak fakt neviem ako to riešiť.

Chci docílit: Aktuálne: Zistiť ako spraviť zobrazilo viac krát ak pri pridaní knihy nastavím, že počet kusov danej knihy bude napr. číslo 3 aby to potom selectovalo, nie ako jeden záznam ale ako 3 knihy s rovnakým názvom, ktoré sa dajú každá zvlášť požičať.

Stači poradiť s tym aktuálnym problémom.

Celkovo: Proste robím klasickú knižnicu s tým, že ju vytváram v PostgresSQL ako DB kde budu jednotlive knihy (názov, vydavateľstvo, rok vydania, žáner, počet kusov, počet strán, cena, jazyk a príloha). Potom zákazníci (meno, priezvisko, číslo zákazníka, mesto, dátum narodenia, počet kníh vypožičaných). Pričom tam mam podmienky rôzne napr. blokovať zákazníka ak ma požičaných a zároveň nevrátených 5 kníh. A potom evidenciu pôžičiek kníh celkovú aj pre jednotlivých zákazníkov teda budem robiť select. A potom to cez WPF aplikáciu budme zobrazovať tie selecty pričom musím vedieť vyhľadávať podla všetkých parametrov kníh podla vydavateľstiev, ale aj kombinovane.

 
Odpovědět 2. ledna 16:12
Avatar
Jirka
Člen
Avatar
Odpovídá na Patrik Živčák
Jirka:2. ledna 19:30

Ahoj,

možná bys mohl zkusit dotaz založený na klíčovém slově DISTINCT.

Tedy něco jako:

--zde se vyberou a vytridi data z TABULKA1 do docasne #TABULKA2
SELECT DISTINCT *
FROM TABULKA1 K1
INTO #TABULKA2;

--tady pozor, smaze se TABULKA1
DELETE *
FROM TABULKA1;

--zde by mělo dojit k obnoveni TABULKY1 z docasne #TABULKY2, bez redundantnich dat
INSERT INTO TABULKA1
FROM #TABULKA2;

Příklady zde: site:itnetwork.cz select distinct into .

Raději si to napřed zazálohuj, dočasné tabulky jsou spíše jen na jedno použití.

HTH!

Nahoru Odpovědět 2. ledna 19:30
Kdo nic nedělá, nic nezkazí.
Avatar
Jirka
Člen
Avatar
Odpovídá na Patrik Živčák
Jirka:2. ledna 21:43

Pročítám si tvůj příspěvek a mám pocit, že by to chtělo kód anebo testovací kousek dat, například kus tabulky s hlavičkou.

Jinak teď mi jako řešení přijde dotaz typu:

SELECT count(K1.ID_KNIHY), K1.NAZEV_KNIHY, K1.ID_AUTORA, K1.NAKLADATELSTVI --atd.
FROM KNIHY1 K1
GROUP BY K1.ID_KNIHY;
Nahoru Odpovědět 2. ledna 21:43
Kdo nic nedělá, nic nezkazí.
Avatar
Patrik Živčák:2. ledna 23:17

CREATE TABLE kniha
(
id_knihy serial not null,
nazov_knihy text not null,
id_vydavtelstvo int not null, -- cudzi kluc na tabulku vydavatelstvo
rok_vydania int,
zaner int, --cudzi kluc na tabulku zaner
cena int,
pocet_kusov int,
pocet_stran int,
cena int,
id_jazyk int, --cudzi kluc na tabulku jazyky
priloha bool
);

INSERT INTO kniha
(nazov_knihy, id_vydavtelstvom, rok_vydania, zaner, cema, pocet_kusov.....)
VALUES
('Janko a marienka', 1, 1992, 1, 100, 4.....) -- to posledne znaci ze pridavam 4ks knihy s nazvom Janko a Marienka

Tak je stavane zadanie mam tam mat ulozene proste x kusov danej knihy alebo aj 1 ale ide o to, ze v tabulke vytvori sa len jeden zaznam a v nom je atribut pocet_kusov samozrejme mozem dat 1 a danu knijhu vytvorit 4x a bue totozna kniha s roznym id_primarneho kluca tj. 4 rozne zaznamy ale tak nieje stavane to zadanie mam tam mat ten parameter pocet_kusov co znaci ze v mojej virtualnej kniznici su 4kusi tej knhy a teda 4 ludia si ju mozu pozicat len neviem ako to spravit aby v neskorsje casti ulohy realne slo to pozicat akoze 4 zakaznikom kedze je to stae jedne zaznam v tej tabulke ked to vytvorim takto.

 
Nahoru Odpovědět 2. ledna 23:17
Avatar
Odpovídá na Patrik Živčák
Matúš Olejník:2. ledna 23:58

Pridaj atribút počet vypožičaných napr. A v aplikácii si dotiahneš informácie o knihách a nakódiš, že ak je počet vypožičaných menší ako celkový počet tak stále môžeš nejakú vypožičať a keď tak urobíš tak updatneš záznam v db kde počet vypožičaných inkrementuješ o jeden, či? :-)

Nahoru Odpovědět 2. ledna 23:58
/* I am not sure why this works but it fixes the problem */
Avatar
Patrik Živčák:3. ledna 0:04

Ahoj to ma nenapadlo zajtra skusim dik inak necham tuto temu živu lebo asi určite ešte niečo pride čo nebudem vedieť zatiaľ dik :D Inak cele na tom programovani je problem, že teoriu viem naspamäť ale riešenie nejakeho aj lahkeho problemu ma proste nenapadne sameho.

 
Nahoru Odpovědět  +1 3. ledna 0:04
Avatar
Patrik Živčák:3. ledna 8:50

Ahojte neviete poradiť jedne s bodov v zadaní je:
Pre jednotlivých zákazníkov je potrebné evidovať minimálne tieto informácie:
• meno
.....
• počet vypožičaných kníh celkom
• zákazník blokovaný (pri počte nevrátených kníh viac ako 5 nastaviť tento príznak automaticky, ale máš možnosť nastaviť tento príznak aj manuálne na obrazovke)

Ide mi o to ak spravím niečo takéto pri vytváraní tabuľky:
CREATE TABLE zakaznik
(
id_zakaznika serial,
....., -- ostatne
pocet_vypozicanych int defalt 0 (check pocet_vypozicanych <= 5),
.....
)
Toto beriem akože nastavím nejaké obmedzenie na počet vypožičaných kníh ale ako zablokujem zákaznika a ešte dôležitejšie ak použijem check ako obmedzenie toho stĺpca tabuľky ako preboha to zmením z aplikácie (WPF aplikácie) ani neviem či sa to dá alebo ako.

Editováno 3. ledna 8:52
 
Nahoru Odpovědět 3. ledna 8:50
Avatar
Odpovídá na Patrik Živčák
Michal Štěpánek:3. ledna 9:34

V první řadě bych cenu knihy nedával jako int, ale jako double.
U zákazníka bych přidal jeden "bool" sloupec, kde by se nastavovala blokace. Tu bys mohl nastavovat checkboxem ručně, nebo by se mohla nastavit automaticky při pokusu o půjčení šesté knihy a rušila by se při vrácení "páté" knihy...
V tabulce knih bys měl evidovat celkový počet a "aktuální počet k půjčení", který by se měnil při půjčení a při vrácení.
Měl bys mít jednu tabulku, kde bys evidoval zápůjčky (id knihy, id zákazníka, datum půjčení, datum vrácení, apod...) a tam by se dal počítat počet aktuálně půjčených knih...

Editováno 3. ledna 9:37
Nahoru Odpovědět 3. ledna 9:34
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:3. ledna 10:16
zakaznik: id_zakaznik, jmeno, prijmeni, adresa...
kniha: id_kniha, nazev, ...
pujceni: id_zakaznik, id_kniha, datum_pujcil, datum_vratil

pocet pujcenych:

SELECT
    COUNT(*) as pocet
FROM
    pujceni
WHERE
    id_zakaznik=123 AND
    datum_vratil=null
GROUP BY
    id_zakaznik
Editováno 3. ledna 10:17
 
Nahoru Odpovědět 3. ledna 10:16
Avatar
Odpovídá na Peter Mlich
Michal Štěpánek:3. ledna 11:11

Myslím, že v tom "selectu" je něco navíc...
buď

WHERE id_zakaznik=123

nebo

GROUP BY    id_zakaznik

obojí dohromady mi v dotazu nedává smysl u

SELECT COUNT(*)
Nahoru Odpovědět 3. ledna 11:11
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Michal Štěpánek
Peter Mlich:3. ledna 14:41

On potrebuje vedet pocet radku.
SELECT * FROM tab WHERE id=123 -- vybere treba 5 radku z vazebni tabulky
Takze to potrebujes zgrupovat podle id a COUNT by mel vratit to cislo 5 a mel by to byt 1 radek. Ale nezkousel jsem to takze to nemusi fungovat :)

Ted si ale uvedomuji, ze s null se pracuje trochu jinak. To by mohl byt spis problem.

datum_vratil=null
datum_vratil IS NULL
Editováno 3. ledna 14:43
 
Nahoru Odpovědět 3. ledna 14:41
Avatar
Odpovídá na Peter Mlich
Michal Štěpánek:3. ledna 15:15

Chápu, že potřebuje počet řádků, ale myslel jsem to tak, že pokud dám podmínku

SELECT COUNT(*) FROM TABLE WHERE ID_zakaznik = 123

tak nemá co "goupovat"...
prostě vyleze číslo počtu záznamů s ID_zakaznik = 123...

Nahoru Odpovědět 3. ledna 15:15
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Michal Štěpánek
Peter Mlich:3. ledna 18:18

pujceni:
id_zakaznik, id_kniha, datum_pujcil, datum_vratil
1, 3, x, x
1, 5, x, x
1, 567, x, x

SELECT vrati
1, 3, x, x
1, 5, x, x
1, 567, x, x
Vsechny radky, kde ID_zakaznik = 1, ty jsou preci 3. To vybiram z vazebni tabulky, ktera nema unikatni id pro radek. (Ale muze mit, mozna by to bylo i lepsi.)

Editováno 3. ledna 18:19
 
Nahoru Odpovědět 3. ledna 18:18
Avatar
Odpovídá na Peter Mlich
Michal Štěpánek:3. ledna 19:14

Toto ano, ale když jsi psal

SELECT COUNT(*)...

tam není co groupovat, protože výsledkem je číslo...

Nahoru Odpovědět 3. ledna 19:14
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Patrik Živčák:4. ledna 11:15

Ahojte znova sa ozývam spravil som si tabuľky hádam všetky, ktoré potrebujem + 2 funkcie v jednej insertujem údaje a tam, nevidím žiadne komplikácie vždy keď zavolám funkciu vytvori sa novy záznam a check v tabuľkách zaručuje že zákaznik si nepožicia viac ako 5 kníh a nevráti ich toľko aby sa dostal do zápornych hodnôt.

Skript na požičanie knihy (ten insert) mi zas updatuje tabuľky kniha a zákaznik aby sa zvyšovali stlpce u zákaznika pocet_aktualne_po­zicanych_knih a u tabuľky kniha: zapozicane_kusy. Tam sa mi to nepodarilo oblbnúť pri skúšani insertu (skript na zapozicanie knihy).

Problém nastáva pri vrátení knihy. Spravil som funkciu kde ju vrátim a taktiež mi tentokrát opačne odčíta hodnoty v stĺpcoch tých istých ako u insertu a check zabezpečí že to nejde pod 0 ani nad stanovenú hranicu. Problém je že môžem vratiť rovnakú knihu viackrát až dokým je parameter zapozicane_kusy > 0 (v tabuľke kniha). Potom to stopne chceck u stlpca v tabulke. Keď to spravím prebehne cely skript a odčíta počet požičaných
kníh v tabulke zákaznik a pocet dostupnych knih v tabulke kniha hoci som vratil už vratenu knihu čo je blbosť.

Mna napadlo, že v tabulke vypozicky mam stlpec vypozicka_vratena typu boolean pri vytvoreni zaznamu sa defaultne nastavi na false a pri vrateni sa nastavi na true. Musim to nejako v funkcii obmedziť cez if, že ak vypozicka_vratena == true uz ta transakcia sa prerusi ale len pri tom danom skripte ale neviem ako to napisať.

Tu je odkaz na funkciu: https://www.itnetwork.cz/…lighter/1136

Editováno 4. ledna 11:17
 
Nahoru Odpovědět 4. ledna 11:15
Avatar
Patrik Živčák:4. ledna 12:48

Vyriešil som to takto vidíte v zdrojaku zasadny problém programatorsku chybu alebo niečo? Niesom až tak skuseny a dobry už vôbec nie. Testoval som to na datach a už ma nepusti vratiť vratenu knihu čo považujem za uspech, ale može bzť že niečo som prehliadol. Odkaz

 
Nahoru Odpovědět 4. ledna 12:48
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 16 zpráv z 16.