SQL lekerdezes

Kezdőlap Fórumok Programozás SQL lekerdezes

8 bejegyzés megtekintése - 1-8 / 8
  • Szerző
    Bejegyzés
  • #1971350
    gabaman
    Felhasználó

      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;

      #1971351
      admin
      Adminisztrátor

        Koszi, 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

        #1971352
        gabaman
        Felhasználó

          Hmm, 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)

          #1971353
          admin
          Adminisztrátor

            Igazabol 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 function

            En 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.

            #1971354
            admin
            Adminisztrátor
              #1971355
              admin
              Adminisztrátor
                #1971356
                gdavid
                Felhasználó

                  egy 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.

                  #1875934
                  csaba
                  Felhasználó

                    Amugy 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 | 9

                    AZ ALTALAM KERESETT LEKERDEZES EREDMENYE EZ LENNE:

                    Code:
                    a | b | p
                    —+—+—
                    3 | 7 | 1
                    5 | 6 | 3
                    4 | 2 | 5
                    1 | 4 | 6
                    6 | 5 | 7

                    Varom az otleteket, biztos van ra valami szep megoldas.

                    KrumpLee

                  8 bejegyzés megtekintése - 1-8 / 8
                  • Be kell jelentkezni a hozzászóláshoz.