Kezdőlap › Fórumok › Programozás › SQL lekerdezes
- This topic has 7 hozzászólás, 4 résztvevő, and was last updated 20 years, 9 months telt el by
gdavid.
-
SzerzőBejegyzés
-
2004-09-10-13:32 #1971350
Tehát az A és a B között 1:N kapcsolat van, lekérdezéseknél az 1:1 leképezést a min(P) bevezetésével oldod meg. Azaz a lekérdezés: SELECT * FROM pelda WHERE a=”A” ORDER BY p ASC LIMIT 1 minden egyes A sorra.
Vhogy így oldanám meg a problémát (röviden, mert sietek):
Code:CREATE TABLE pelda (
id NUMERIC,
a NUMERIC,
b NUMERIC,
p NUMERIC);CREATE TABLE pelda_seged (
a NUMERIC,
id NUMERIC);CREATE PROCEDURE insert (A NUMERIC, B NUMERIC, P NUMERIC) AS
BEGIN
i NUMERIC;
ptr NUMERIC;
INSERT INTO pelda (a, b, p) VALUES (A, B, P);
i = SELECT COUNT(*) FROM pelda WHERE a=A;
IF i=0 THEN
ptr = SELECT id FROM pelda WHERE a=A;
INSERT INTO pelda_seged VALUES (ptr, A);
ELSE
ptr = SELECT id FROM pelda WHERE a=A ORDER BY p ASC LIMIT 1;
UPDATE pelda_seged SET id = ptr, a=A;
ENDIF
END;CREATE PROCEDURE delete (A NUMERIC, B NUMERIC, P NUMERIC) AS
BEGIN
i NUMERIC;
ptr NUMERIC;
DELETE FROM pelda WHERE a=A, b=B, p=P;
i = SELECT COUNT(*) FROM pelda WHERE a=A;
IF i=0 THEN
DELETE FROM pelda_seged WHERE a=A;
ELSE
ptr = SELECT id FROM pelda WHERE a=A ORDER BY p ASC LIMIT 1;
UPDATE pelda_seged SET id = ptr, a=A;
ENDIF
END;Lekerdezes:
SELECT pelda.* FROM pelda, pelda_seged WHERE pelda.id = pelda_seged.id;2004-09-10-17:40 #1971351Koszi, ez is jo megoldas, de en valami olyanra gondoltam, ahol nincsenek segedtablak, es nem definialunk fuggvenyeket sem, csak egy egyszeru lekerdezes, ami tartalmaz nehany beagyazott lekerdezest is, GROUP BY, JOIN meg hasonlo magiakat hasznal, de semmi egyeb.
Code:SELECT a, b, p FROM pelda WHERE p IN (SELECT min(p) FROM pelda GROUP BY a)Szoval valami ehhez hasonlot keresek. Ez azert nem jo, mert csak akkor mukodik, ha a P egyedi ertekeket tartalmaz, ha ismetlodhet, akkor mar gondok lehetnek, gondolom ezt latja mindenki. De talan ebbol kiindulva valakinek lesz valami otlete.
Ez a lekerdezes szinte tokeletesen azt adja vissza, amit kell, csak azokban a sorokban van gond, ahol a P erteke ugyanaz, a tobbi sor „tiszta”, de talan meg erre a lekerdezesre is lehetne valami szigorito feltetelt szabni (vagy esetleg metszet, vagy kivetel kepzessel), es akkor ez is megoldodna. Igazabol ez egy nagyon egyszeru gond, meglep, hogy ilyen nehez ra egyszeru lekerdezest talalni. Nekem legalabbis nagyon nehez, mert meg nem talaltam, csak eddig jutottam vele.Azert megegyszer koszi a valaszt, sokat tanultam belole.
Szoval tovabbra is varom az otleteket, vagy a
Code:SELECT a, b, p FROM pelda WHERE p IN (SELECT min(p) FROM pelda GROUP BY a)lekerdezes „tovabbfejlesztett” valtozatat.
KrumpLee
2004-09-10-20:39 #1971352Hmm, a PostgreSQL nagyon sok mindent ismer, azt gondoltam jelent vmit, hogy az elején kihangsúlyoztad. Tehát SQL’92 megoldás kell, íme:
Code:SELECT * FROM pelda GROUP BY a HAVING p = MIN(p);Problémák:
– nem hatékony, sokkal lassabb, mint az elõbbi megoldás
– egyezõ priorításokat nem lehet szûrni: a p = MIN(p) helyett nem lehet betenni részlistát
– ha ez egy részprobéma, akkor a részmegoldások nem minden esetben vagy rendkívül nehezen kombinálhatóak
– a GROUP BY a feltételben az a értékeit nem lehet behelyettesíteni (késõbb gond lehet)2004-09-10-22:30 #1971353Igazabol ezt probaltam meg legelosszor, de nem sikerult mukodesre birnom. A kovetkezo hibauzenetet kapom:
ERROR: Attribute pelda.b must be GROUPed or used in an aggregate functionEn ugy tudom, hogy ami a select utan van, annak a group by utan is jelen kell lennie. Viszont akkor nincs ertelme a lekerdezesnek, mert pont a lenyeg veszik el.
Ezert irtam ugy a lekerdezest az elozo hozzaszolasomban.
Ha neked maskepp mukodne, vagy lenne erre valami megoldasod, akkor arra kivancsi lennek.
2004-09-22-18:52 #19713542004-09-22-19:27 #19713552004-09-22-20:30 #1971356egy masik megoldas:
Code:select tabla1.*
from tabla1,
( select a,max(p) as p from tabla1 group by a ) vmi
where vmi.a=tabla1.a and vmi.p=tabla1.p
order by a;ha a legkisebb p-re vagyunk kivancsiak termeszetesen MAX-helyett MIN legyen fuggveny.
bar szerintem a ertelmesebb dolog a max-ot keresni, mert igy lehet ujabbat beirni egyszeruen.de ez mar legyen a te gondod.
🙂
D.
2009-12-04-19:56 #1875934Amugy Postgresqlben probalkoztam azzal, hogy megoldjam a kovetkezo SQL dilemmat:
Kepzeljunk el egy SQL tablat, melynek 3 oszlopa van. Az elso oszlop neve legyen A, a masodike B, a harmadike P. Az A es B egyszeruen egesz sz’m ertekek tarolasara szolgal. A P oszlopban is egesz szmok vannak, de ez az oszlop arra szolgál, hogy ez alapjan az oszlop alapjan rendezzuk sorba a tablakat, tehat a P a prioritast jelenti.A lenyeg, hogy egy B szamhoz egyertelmuen kell tudnunk pontosan egy B erteket megadni, de lista szeruen kell a lekerdezes eredmenyeben szerepelnie. Magyarul A oszlopra nem adhatunk meg kitetelt.
Ebbol a tablabol egy olyan listat kell adni, hogy egyertelmuen meg tudjuk mondani, barmely A-hoz tartozo B erteket. Mivel A oszlopban egy ertekbol tobb is allhat, ezert kell a P oszlop. A P oszlop alapjan rendezve, a A oszlop ismetlodo elemei kozul csak a kisseb P ertekkel rendelkezo kerulhet a listaba.
Maskepp fogalmazva:
Az A es B oszlop szamparokat alkotnak. A lenyeg, hogy ezek a szamparok alapbol nem biztos, hogy fugvenykent is funkcionalnanak, tehat nem biztos, hogy egy A ertekhez pontosan egy B tartozik. Ezert a P oszlop erre megoldast nyujt. Minden A ertekhez, amihez tobb B tartozik, az alapjan dontjuk el melyik B-t rendeljuk, hogymelyikhez kissebb a P erteke.Egy egyszeru SELECT * FROM pelda ORDER BY p;
pelda:Code:a | b | p
—+—+—
3 | 7 | 1
3 | 1 | 2
5 | 6 | 3
5 | 4 | 4
4 | 2 | 5
1 | 4 | 6
6 | 5 | 7
6 | 2 | 8
6 | 1 | 9AZ ALTALAM KERESETT LEKERDEZES EREDMENYE EZ LENNE:
Code:a | b | p
—+—+—
3 | 7 | 1
5 | 6 | 3
4 | 2 | 5
1 | 4 | 6
6 | 5 | 7Varom az otleteket, biztos van ra valami szep megoldas.
KrumpLee
-
SzerzőBejegyzés
- Be kell jelentkezni a hozzászóláshoz.
legutóbbi hsz