Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
Je moet dan wel nog kijken naar id's met dezelfde parent. Een algoritme opstellen die dan de "jongste" parent bekijkt moet er dan nog tussen, en dat wordt denk ik lastiger.
Dan kan ik je niet helpen4of9 schreef op maandag 08 mei 2006 @ 15:28:
Het moet helaas wel in SQL (TSQL om precies te zijn, ik gebruik MSSQL)
[ Voor 23% gewijzigd door mithras op 08-05-2006 15:32 ]
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
Maak een user-defined function die de diepte teruggeeft?4of9 schreef op maandag 08 mei 2006 @ 15:28:
Het moet helaas wel in SQL (TSQL om precies te zijn, ik gebruik MSSQL)
Even uit de blote bol:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| CREATE FUNCTION [dbo].[GetDepthForMyNode] ( @intID as int ) RETURNS Int AS BEGIN Declare @intDepth as int Set @intDepth = 0 While not (@intID is null) BEGIN Select @intID = parent_id from mytable where id = @intID Set @intDepth = @intDepth + 1 END Return @intDepth END |
Daarna kun je met een
1
| Select id, dbo.GetDepthForMyNode(id) as diepte from mytable |
Je begrijpt dat dit wel een (redelijk/behoorlijk) dure operatie is op veel records of veel "diepte".
Origineel, maar als nodes van parent wisselen zou dit wel eens gevaarlijk kunnen zijn (vergeten niveau te updaten enzo, maar daar heb je SP's voorJanoz schreef op maandag 08 mei 2006 @ 15:33:
Als je de volgende dingen hebt:
* Een conditionele lus
* Het achterhalen van het aantal geupdate velden
Zou je het volgende kunnen doen:
Zorg dat alle niveau velden NULL zijn. en zet het niveau van de parrent op 0. Draai een query waarbij je twee niveau's joint en filter deze op parent niveau != null en eigen niveau null en ken aan het eigen niveau dan parentniveau + 1 toe. Dit doe je net zo lang tot het aantal geupdate rijen 0 is.
Bij mijn weten kan dat niet, of je moet met EXEC gaan rommelen enzo... Weet overigens ook niet of dat bij functions wel kan... dat zou mijn oplossing nog iets kunnen versimpelen wellicht.TallManNL schreef op maandag 08 mei 2006 @ 15:36:
Ik heb overigens niet gecheckt of stored procs recursie mogen toepassen.
[ Voor 122% gewijzigd door RobIII op 08-05-2006 15:49 ]
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.
Je eigen tweaker.me redirect
Over mij
* Een conditionele lus
* Het achterhalen van het aantal geupdate velden
Zou je het volgende kunnen doen:
Zorg dat alle niveau velden NULL zijn. en zet het niveau van de parrent op 0. Draai een query waarbij je twee niveau's joint en filter deze op parent niveau != null en eigen niveau null en ken aan het eigen niveau dan parentniveau + 1 toe. Dit doe je net zo lang tot het aantal geupdate rijen 0 is.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Ik heb overigens niet gecheckt of stored procs recursie mogen toepassen.
geheelonthouder met geheugenverlies
Ik moet wel even afvangen dat als de parent_id null is dat dan het niveau = 0
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
| Alter Function GetNodeDepth
(
@intID as int
)
Returns Int
As
Begin
Declare @intDepth int
Set @intDepth = 0
While not (@intID is null)
Begin
SELECT @intID = parent_id --, parent_id
FROM test_boom_old
WHERE id = @intID
If(NOT @intId IS NULL)
Begin
Set @intDepth = @intDepth + 1
End
End
Return @intDepth
End |
En dan met de volgende update functie wordt de tweede tabel gevuld met niveau's
1
2
3
| update test_boom set niveau = dbo.GetNodeDepth(t.id) from test_boom t,test_boom_old tbo where t.id = tbo.id |
ik ga de boel nog even testen!
super bedankt, ik vreesde al voor recursieve functies etc...
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
Als je die diepte maar "sporadisch" nodig hebt ben je gek als je deze "hard" in de tabel gaat opslaan. Je kunt deze functie in iedere query gebruiken wanneer je 'm nodig hebt en dan is 't altijd kloppend. Heb je de diepte veel en vaak nodig dan kun je 'm inderdaad beter bij de node opslaan, maar vergeet 'm dan niet bij te werken op het moment dat de node van parent wijzigt. Erger: Wat als de parent van parent wijzigt? Dan moet je dus ook alle childnodes bijwerken. Al met al een boel administratieve taken die je dan dus NIET moet vergeten, wil je je DB consistent houden.4of9 schreef op maandag 08 mei 2006 @ 15:55:
Die userdefined function werkt prima.
En dan met de volgende update functie wordt de tweede tabel gevuld met niveau's
code:
1 2 3 update test_boom set niveau = dbo.GetNodeDepth(t.id) from test_boom t,test_boom_old tbo where t.id = tbo.id
ik ga de boel nog even testen!
super bedankt, ik vreesde al voor recursieve functies etc...
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.
Je eigen tweaker.me redirect
Over mij
Betreft het echter een eenmalige omzetting, dan zou ik me er niet zo druk over maken
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Uiteraard eensch is. Ik zei het misschien wat kromJanoz schreef op maandag 08 mei 2006 @ 17:11:
Als het je om efficientie gaat, en je zet het sowieso in een nieuwe tabel, dan kun je beter mijn algoritme gebruiken ipv de getNodeDepth functie. In mijn functie worden er (3 + max diepte) queries uitgevoerd terwijl de andere oplossing (aantal elementen * gemiddelde diepte) queries uitvoert. Dat laatste aantal is significant hoger dan het eerste.
Betreft het echter een eenmalige omzetting, dan zou ik me er niet zo druk over maken..
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.
Je eigen tweaker.me redirect
Over mij