select een op meer relatie, maar dan 2 kanten op

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Veur Heur

Veur Heur

26/05/2023 09:59:13
Quote Anchor link
Ik ben bezig met de volgende uitbreiding op mijn dochter's achtbanenteller. Het komt regelmatig voor dat we een achtbaan tegenkomen dat hetzelfde model is als een achtbaan reeds eerder toegevoegd aan de lijst. Dit wordt door de kenners een "clone" genoemd. Aangezien we inmiddels zoveel van deze clones zijn tegengekomen, leek het me leuk een relatie tussen deze te maken in de database. Hiervoor heb ik een tabel aangemaakt genaamd "clones" met daarin 2 kolommen namelijk:

- achtbaanid_1
- achtbaanid_2

(ja ik had wellicht ook achtbaanid en cloneid kunnen gebruiken)

Het idee is om originele id in te voegen als achtbaanid_1 met de clone als achtbaanid_2, een één op meer relatie dus. Ik wil deze echter 2 kanten op kunnen query-en, m.a.w. als ik het origineel op vraag wil ik een lijst met clones, maar als ik een clone op vraag, wil ik een lijst met andere clones inclusief het origineel.

Zover zo goed. Ik gebruik nu echter 2 queries waarvan ik me afvroeg of dat niet makkelijker kan:

- SELECT * FROM clones WHERE achtbaanid_1=?
- SELECT * FROM clones WHERE achtbaanid_1=(SELECT achtbaanid_1 FROM clones WHERE achtbaanid_2=?) AND achtbaanid_2!=?

De eerste levert bij het origineel een lijst met clones op (en wordt bij een clone dus overgeslagen).
De tweede levert bij een clone een lijst met clones op (en wordt bij het origineel dus overgeslagen).

Probleem bij de tweede query is alleen dat het origineel niet wordt meegenomen terwijl ik deze wél in de lijst wil als ik een clone toon. Simpele oplossing zou zijn om het origineel in te voegen als zijnde clone (m.a.w. achtbaanid_1=achtbaanid_2), maar kan dit niet handiger? Kan het zelfs niet met 1 query i.p.v. 2?

Benieuwd naar jullie gedachten.
Gewijzigd op 26/05/2023 10:00:21 door Veur Heur
 
PHP hulp

PHP hulp

19/05/2024 17:38:30
 
Adoptive Solution

Adoptive Solution

26/05/2023 13:20:09
Quote Anchor link
Op basis van de beschrijving heb ik dit bedacht.

Moet maar even kijken of het in de buurt komt.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
-- Adminer 4.8.1 MySQL 10.6.12-MariaDB-0ubuntu0.22.04.1 dump

SET NAMES utf8;
SET time_zone = '+00:00';
SET foreign_key_checks = 0;
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';

DELIMITER ;;

DROP PROCEDURE IF EXISTS `getClones`;;
CREATE PROCEDURE `getClones`(IN `clone` tinyint)
BEGIN
SET @ab = (SELECT ab1 FROM clones WHERE ab2 = clone);
#SELECT * FROM clones WHERE ab1 = @ab;
SELECT achtbaan.*, clones.*
FROM achtbaan
JOIN clones
ON achtbaan.id = clones.ab1
WHERE ab1 = @ab;
END;;

DROP PROCEDURE IF EXISTS `spAchtbaanLeftJoinClones`;;
CREATE PROCEDURE `spAchtbaanLeftJoinClones`()
BEGIN
# achtbaan met of zonder clones
SELECT achtbaan.*, clones.*
FROM achtbaan
LEFT JOIN clones
ON achtbaan.id = clones.ab1;
END;;

DROP PROCEDURE IF EXISTS `spAchtbaanRightJoinClones`;;
CREATE PROCEDURE `spAchtbaanRightJoinClones`()
SELECT achtbaan.*, clones.*
FROM achtbaan
RIGHT JOIN clones
ON achtbaan.id = clones.ab1;;

DELIMITER ;

SET NAMES utf8mb4;

DROP TABLE IF EXISTS `achtbaan`;
CREATE TABLE `achtbaan` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `naam` char(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

INSERT INTO `achtbaan` (`id`, `naam`) VALUES
(1,    'Achtbaan 1'),
(2,    'Achtbaan 2'),
(3,    'Achtbaan 3'),
(4,    'Achtbaan 4');

DROP TABLE IF EXISTS `clones`;
CREATE TABLE `clones` (
  `ab1` int(11) NOT NULL,
  `ab2` int(11) NOT NULL,
  `naam` char(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

INSERT INTO `clones` (`ab1`, `ab2`, `naam`) VALUES
(1,    1,    'Clone 1 Achtbaan 1'),
(1,    2,    'Clone 2 Achtbaan 1'),
(2,    3,    'Clone 1 Achtbaan 2'),
(3,    4,    'Clone 1 Achtbaan 3');

-- 2023-05-26 11:16:49


Toevoeging op 26/05/2023 13:45:56:

Om de benaming uniform te maken hernoem getClones naar spGetClones

Toevoeging op 26/05/2023 13:48:37:

En voor de volledigheid, zo roep je de procedures aan.

Gebruik als variable een php variabele.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
SET @getClone = 3;
CALL spGetClones(@getClone);

CALL spAchtbaanLeftJoinClones();
CALL spAchtbaanRightJoinClones();
 
Ivo P

Ivo P

26/05/2023 14:35:23
Quote Anchor link
Mijn idee:
Is een Fiat 500 een clone van een andere Fiat 500, of is "fiat 500" een type?

Ik zou de achtbaan een omschrijvende naam geven met een ID.

En de Baron uit de Efteling is dan typeID = 10;
En als een Euro-Disney een clone daarvan staat, dan heeft die ook typeID = 10.

Dat lijkt me eenvoudiger dan 1 achtbaan als moeder-baan aan te wijzen en de andere banen daarvan een clone te laten zijn.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.