Avatar billede andrew Juniormester
29. december 2023 - 23:17 Der er 4 kommentarer og
1 løsning

Opret URL via database-struktur

Hej eksperter

Jeg har en database med kategorier, hvori jeg ønsker, ud fra et id, at få returneret url'en. I dag har jeg en funktion, som løber igennem alle rækkerne, men for at undgå for mange forespørgsler tænker jeg, om det er muligt at udføre i én forespørgsel.

Databasen
id        level        url
1        null        movies
2        1        dvd
3        2        horror
4        2        action

Null er top-kategori, id 2 er en underkategori af id 1 osv.

Eksempelvis ønsker jeg ved forespørgsel på id 3, at resultatet er:
"movies/dvd/horrer"

Forespørgsel på id 2 vil være:
"movies/dvd".

Er det muligt, at få ovenstående ud fra én forespørgsel, eventuelt ud fra en array eller lignende?
Avatar billede expnet Seniormester
29. december 2023 - 23:28 #1
Jeg tror ikke helt jeg forstår hva det er præcis du vil
Avatar billede andrew Juniormester
29. december 2023 - 23:38 #2
En forespørgsel skal lave et loop igennem rækkerne i databasen, med start fra det id der bliver angivet, og via loopet løbe igennem de id'er som "level" referere til.

Jeg ved slet ikke om det kan lade sig gøre og der egentlig blot et forsøg på et alternativ end det beskrevne.

Jeg ønsker at kunne forespørge på eksempel "id 4" og derfra få lavet et loop igennem databasen og få resultatet "movies/dvd/action", da "id 4" er på "level 2" som i følge id er "dvd". Dvd er i "level 1" som er "movies", ergo id 1. Giver det mening?
Avatar billede arne_v Ekspert
30. december 2023 - 02:35 #3
Hvis du bruger Oracle som database er der en elegant løsning.

Med alle databaser er der hvis du kan sætte et maksimum på antal led en brugbar løsning.

Demo:

mysql> CREATE TABLE tt (
    ->    id INTEGER NOT NULL,
    ->    parent INTEGER,
    ->    part VARCHAR(32),
    ->    PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.11 sec)

mysql> INSERT INTO tt VALUES(1, NULL, 'movies');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO tt VALUES(2, 1, 'dvd');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO tt VALUES(3, 2, 'horror');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO tt VALUES(4, 2, 'action');
Query OK, 1 row affected (0.01 sec)

mysql>
mysql> SELECT t1.part,t2.part,t3.part,t4.part
    -> FROM tt t1 LEFT JOIN tt t2 ON t1.parent=t2.id
    ->            LEFT JOIN tt t3 ON t2.parent=t3.id
    ->            LEFT JOIN tt t4 ON t3.parent=t4.id
    -> WHERE t1.id = 3;
+--------+------+--------+------+
| part  | part | part  | part |
+--------+------+--------+------+
| horror | dvd  | movies | NULL |
+--------+------+--------+------+
1 row in set (0.00 sec)

mysql>
mysql> SELECT t1.part,t2.part,t3.part,t4.part
    -> FROM tt t1 LEFT JOIN tt t2 ON t1.parent=t2.id
    ->            LEFT JOIN tt t3 ON t2.parent=t3.id
    ->            LEFT JOIN tt t4 ON t3.parent=t4.id
    -> WHERE t1.id = 4;
+--------+------+--------+------+
| part  | part | part  | part |
+--------+------+--------+------+
| action | dvd  | movies | NULL |
+--------+------+--------+------+
1 row in set (0.00 sec)

mysql>
mysql> DROP TABLE tt;
Query OK, 0 rows affected (0.01 sec)
Avatar billede andrew Juniormester
30. december 2023 - 12:29 #4
Hej Arne

Det er perfekt. Giver god forståelse.

Tak for hjælpen!
Avatar billede arne_v Ekspert
30. december 2023 - 16:54 #5
Og hvis nogen undrer sig over hvad Oracle kan gøre bedre:

SQL> CREATE TABLE tt (
  2      id INTEGER NOT NULL,
  3      parent INTEGER,
  4      part VARCHAR(32),
  5      PRIMARY KEY(id)
  6  );

Table created.

SQL> INSERT INTO tt VALUES(1, NULL, 'movies');

1 row created.

SQL> INSERT INTO tt VALUES(2, 1, 'dvd');

1 row created.

SQL> INSERT INTO tt VALUES(3, 2, 'horror');

1 row created.

SQL> INSERT INTO tt VALUES(4, 2, 'action');

1 row created.

SQL>
SQL> SELECT part FROM tt START WITH id = 3 CONNECT BY PRIOR parent = id;

PART
--------------------------------
horror
dvd
movies

SQL> SELECT part FROM tt START WITH id = 4 CONNECT BY PRIOR parent = id;

PART
--------------------------------
action
dvd
movies

SQL>
SQL> DROP TABLE tt;

Table dropped.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester