Toon posts:

[MYSQL] query, mysql < 4

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo,

Ik wil een overzichtje hebben, wat ik maar niet voor elkaar krijg.

Poging 1

code:
1
2
3
4
5
6
id | naam | f_id | source_id
-----------------------------
 1 | spel |    1 |        0 
 2 | bal  |    1 |        0
 3 | dop  |    2 |        1
 4 | kurk |    3 |        1


Wat ik wil hebben is:
code:
1
2
3
4
id | naam | f_id | source_id
--------------------------
 2 | bal  |    1 |         0
 3 | dop  |    2 |         1


Ik wil alle records, waar f_id is 1 of 2.
Daarbij kan het zijn dat er een waarde vervangen moet worden door een andere (een vervanging). In het voorbeeld zie je dat dop spel vervangt.

SQL mbv subquery (niet getest):
code:
1
2
3
4
SELECT *
FROM tabel
WHERE (f_id = 1 OR f_id = 2) 
      AND id NOT IN s_id


Overige pogingen (kort):
code:
1
2
SELECT *
FROM tabel A LEFT JOIN tabel B ON A.id = B.id



Probleem is dus dat ik de SQL code niet werkend krijg naar eentje die MySQL 3.23 ondersteunt.


Poging 2

code:
1
2
3
4
5
6
id | naam | f_id | join_id
---------------------------
 1 | spel |    1 |      1
 2 | bal  |    1 |      2
 3 | dop  |    2 |      1
 4 | kurk |    3 |      1


Wat ik wil hebben is:
code:
1
2
3
4
id | naam | f_id | join_id
------------------------
 2 | bal  |    1 |       2
 3 | dop  |    2 |       1


Ik wil alle records, waar f_id is 1 of 2.
Daarbij kan het zijn dat er een waarde vervangen moet worden door een andere (een vervanging). In het voorbeeld zie je dat dop spel vervangt.

SQL mbv subquery (niet getest):
code:
1
2
3
4
5
SELECT *
FROM tabel
WHERE (f_id = 1 OR f_id = 2) 
GROUP BY join_id
HAVING (count(join_id) > 1 AND id <> join_id) OR (count(join_id) = 1 AND id = join_id)


Zonder die count weet je niet zeker dat tie de nieuwe naam pakt. Vandaar die rare constructie die niet werkt, alleen wel laat zien wat ik bedoel.

Overige pogingen (kort):
code:
1
2
3
4
SELECT *
FROM tabel A, tabel B
WHERE (A.f_id = 1 OR A.f_id = 2)
      AND (B.f_id = 1 OR B.f_id = 2)



Algemeen
1. Per f_id is source_id uniek. (een originele waarde kan niet door meerdere waardes vervangen worden.)
2. Ik sta open voor database wijzigingen
3. Het is niet uitgesloten dat het met de overige pogingen kort niet kan, alleen ik kom er niet uit.

Gevonden topics op GoT:
subquery > join...Hoe dan???
[rml][ MySQL] subquery oplossing gezocht[/rml]


Iemand een oplossing?

[ Voor 1% gewijzigd door Verwijderd op 24-12-2003 15:03 . Reden: typo's ]


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op 24 december 2003 @ 15:02:
Algemeen
1. Per f_id is source_id uniek. (een originele waarde kan niet door meerdere waardes vervangen worden.)
2. Ik sta open voor database wijzigingen
Ik denk dat je die relatie f_id vs source_id een beetje beter kan gebruiken/uitdrukken dan je nu hebt. (tip, geef volgende keer je relaties betere namen, zodat ze meer uitdrukken waar het om gaat en het model beter leesbaar is, liefst ook de namen voor je tabellen zelf)
Maar eerlijk gezegd snap ik weinig van je velden, wat zijn de relaties onderling? Wat drukken de bepaalde waardes uit tov elkaar?
Waarom wordt spel niet geselecteerd en bal wel (ondanks dat ze beide een f_id 1 hebben).

Als je relaties tussen een stel objecten met een ander stel objecten wilt uitdrukken kan je dat wellicht beter met twee tabellen uitdrukken.

Met zoiets bijvoorbeeld:
tabel_objecten: id, naam
tabel_relaties: id, f_id

't Voordeel is dat je dan niet verplicht bent voor elk object een f_id op te stellen, met als gevolg dat je alleen die records in de relatie-tabel hoeft te bewaren die je _wil_ bewaren (evt kan je alsnog een f_id opslaan in je objecten-tabel, als je perse wilt weten bij welk f_id ze horen, dan verplaats je alleen de source_id-relatie naar een externe tabel).

[ Voor 13% gewijzigd door ACM op 24-12-2003 15:40 ]


Verwijderd

Topicstarter
F-id = is een filiaal

het kunstje is dat er een default filiaal komt, waarin default waardes zijn. In dit geval is f_id = 1 het default filiaal. Tevens kunnen er nieuwe filialen worden toegevoegd. Deze filialen krijgen standaard alle categorieën van default. Er moet een mogelijkheid zijn hier uitzonderingen op te maken. Ook uitbreidingen zijn mogelijk. Die uitzonderingen (exceptions) en uitbreidingen zijn uniek voor niet-default filialen).

code:
1
2
3
4
5
6
id | f_id | naam | source_id | 
----------------------------
 1 |    1 | aaaa |       0 |        default waarde
 2 |    1 | bbbb |       0 |        default waarde
 3 |    2 | cccc |       1 |        exception op default waarde 1, van filiaal 2
 4 |    2 | dddd |       4 |        uitbreiding van filiaal 2



1. Wat ik wil is een overzichtje van alle default waarden, die geen exception hebben
--> id: 2
2. Alle exceptions
--> id: 3
3. Alle uitbreidingen
--> id: 4

code:
1
2
3
4
5
id | f_id | naam | source_id | 
----------------------------
 2 |    1 | bbbb |       0 |        default waarde
 3 |    2 | cccc |       1 |        exception op default waarde 1, van filiaal 2
 4 |    2 | dddd |       0 |        uitbreiding van filiaal 2


Je kunt dus niet simpelweg alles pakken waarvan f_id = 1 of f_id = 2, want dan krijg je de originele waarde ook terug, terwijl die wordt overschreven door een exception.

MYSQL 4:
code:
1
2
3
4
SELECT *                 //selecteer alles
FROM tabel            // van de tabel
WHERE (f_id = 1 OR f_id = 2)      //waar filiaal is default of 2 (specifieke filiaal)
      AND id NOT IN source_ID   // zorgt voor filitering op orginele waardes


Dit gaat alleen niet werken in Mysql 3.23

Verder zijn er nog meer typen filialen mogelijk die gebruik maken van deze tabel. Hiervan krijg ik wel netjes de categorieen die specifiek bij dat filiaal horen terug. Alleen hier heb ik problemen mee.

Wat betreft die naamgeving: ik heb dat zo bewust gedaan voor GoT. Anders wordt het overzicht zo breed 8)7 . f_id heet dan ook filiation_id. etc etc.

In ieder geval bedankt voor je reactie :D , hopelijk snap je het probleem met bovenstaande toelichting wel.

Verwijderd

Topicstarter
(kick)

Ben de komende dagen weg, dus kan geen antwoorden meer geven. Probleem heb ik nog steeds. Mocht iemand nog een idee / oplossing hebben, please reply :)

Verwijderd

Hier is de SQL query die je het gewenste resultaat geeft.


select a.* from tabel a left join tabel b on a.id = b.source_id where a.f_id in (1,2) and a.id not in (b.source_id);


code:
1
2
3
4
id | naam | f_id | source_id
--------------------------
 2 | bal  |    1 |       0
 3 | dop  |    2 |       1


Het keyword "IN" wordt ondersteund door versie 3.23 dus... :+

Greetings and a happy new year!! ;),

Björn

Verwijderd

Topicstarter
Ben net terug van weggeweest, gelijk even gekeken en jawel een reply! :)

[ Voor 31% gewijzigd door Verwijderd op 05-01-2004 09:51 ]


Verwijderd

Topicstarter
Bemerkt net, nu ik weer verder bezig ben dat bovenstaande query niet goed werkt.

Stel dat een ander filiaal (dus geen 1 of 2) ook een exception maakt. Dan gaat:
code:
1
a.id not in (b.source_id);


Niet meer op. Dit geld alleen als filiation_id=2.

Simpelweg
code:
1
AND b.filiation_id IN (1,2)

toevoegen werkt ook niet, aangezien je dan een aantal joins weghaald die wel aanwezig moeten zijn.

Daarom heb ik deze code, maar ik snap niet waarom de NOT IN niet werkt:
code:
1
2
3
4
5
6
7
SELECT * 
FROM tabel
WHERE f_id
IN ( 1, 2 ) AND s_id NOT 
IN (
id
)


De
code:
1
2
3
4
AND s_id NOT 
IN (
id
)

lijkt niet uitgevoerd te worden. In het overzichtje staan nog steeds ids die ook in s_id staan. Waarom werkt het niet?

Verwijderd

Topicstarter
Na een beetje gepuzzel ben ik eruit.
Deze reply is voor de search. Topic mag op slot.

Goede SQL is:
code:
1
2
3
4
5
6
7
8
SELECT a. * 
FROM tabel a
LEFT JOIN tabel b ON a.id = b.source_id AND b.f_id =2
WHERE a.f_id
IN ( 1, 2 ) AND a.id NOT 
IN (
b.source_id
)
Pagina: 1