Fetstil Fetstil Kursiv Understrykning linje färgläggning tabellverk Punktlista Nummerlista Vänster Centrerat högerställt Utfyllt Länk Bild htmlmode
  • Forum & Blog
    • Forum - översikt
      • .Net
        • asp.net generellt
        • c#
        • vb.net
        • f#
        • silverlight
        • microsoft surface
        • visual studio .net
      • databaser
        • sql-server
        • databaser
        • access
        • mysql
      • mjukvara klient
        • datorer och komponenter
        • nätverk, lan/wan
        • operativsystem
        • programvaror
        • säkerhet, inställningar
        • windows server
        • allmänt
        • crystal reports
        • exchange/outlook
        • microsoft office
      • mjukvara server
        • active directory
        • biztalk
        • exchange
        • linux
        • sharepoint
        • webbservers
        • sql server
      • appar (win/mobil)
      • programspråk
        • c++
        • delphi
        • java
        • quick basic
        • visual basic
      • scripting
        • asp 3.0
        • flash actionscript
        • html css
        • javascript
        • php
        • regular expresssion
        • xml
      • spel och grafik
        • DirectX
        • Spel och grafik
      • ledning
        • Arkitektur
        • Systemutveckling
        • krav och test
        • projektledning
        • ledningsfrågor
      • vb-sektioner
        • activeX
        • windows api
        • elektronik
        • internet
        • komponenter
        • nätverk
        • operativsystem
      • övriga forum
        • arbete karriär
        • erbjuda uppdrag och tjänster
        • juridiska frågor
        • köp och sälj
        • matematik och fysik
        • intern information
        • skrivklåda
        • webb-operatörer
    • Posta inlägg i forumet
    • Chatta med andra
  • Konto
    • Medlemssida
    • Byta lösenord
    • Bli bonsumedlem
    • iMail
  • Material
    • Tips & tricks
    • Artiklar
    • Programarkiv
  • JOBB
  • Student
    • Studentlicenser
  • KONTAKT
    • Om pellesoft
    • Grundare
    • Kontakta oss
    • Annonsering
    • Partners
    • Felanmälan
  • Logga in

Hem / Forum översikt / inlägg

Posta nytt inlägg


Artikelträd och SQL

Postades av 2008-05-27 09:45:27 - Stefan Johansson, i forum databaser, Tråden har 7 Kommentarer och lästs av 1706 personer

Hej!

Har en sql-fråga jag skulle behöva hjälp med. Jag håller på med en applikation där man ska kunna få fram artiklar (på toppnivå) som innehåller andra artiklar man specificerat. Bifogat finns en pdf, www.stefanj.se/articletree.pdf som föreställer ett artikelträd. Databasstrukturen är fast och kan inte ändras. Artikelträdet är skapat genom att i en länktabell specificera barnnoder till föräldernoder.

I nedanstående exempel har jag valt att kolla två artiklar, men man ska lika gärna kunna välja ut ett godtyckligt antal artiklar och söka de artiklar som innehåller dessa.

Scenario 1:
Vilka artiklar ingår artikel 1180 SV och artikel MB0040 i samtidigt?
Argument: ObjectId 2, ObjectId 4
Resultat: ObjectId 1

Scenario 2:
Vilka artiklar ingår artikel FE0067 och AA2250 i samtidigt?
Argument: ObjectId 8, ObjectId 11
Resultat: null, dvs inga artiklar

Scenario 3:
Vilka artiklar ingår AA2250 och AA2251 i samtidigt?
Argument: ObjectId 11, ObjectId 12
Resultat: ObjectId 10

Scenario 4:
Vilka artiklar ingår FE0067 och 1180 SV i samtidigt?
Argument: ObjectId 8, ObjectId 2
Resultat: ObjectId 9, ObjectId 1

Några goda ideer?

/Mvh Stefan


Svara

Sv: Artikelträd och SQL

Postades av 2008-05-27 10:07:23 - Niklas Jansson

Har svårt att se att detta löses med "ren sql", i synnerhet om du är låst till den skumma strukturen.
För det första är jag tveksam till om din graf är rätt, du verkar ha två stycken MB0040, ingenting i 9 och 8, AA2251 kan jag inte hitta osv. Jag förstår ärligt talat inte vad de tre kolumerna betyder.

Men om jag ändå tolkat dig rätt skulle jag göra en lösning i stil med:

1. För varje input, ta fram "tråden" upp till översta föräldern.
ObjectId 4 -> ObjectId 3 -> ObjectId 1
ObjectId 2 -> ObjectId 1
2. Om vi nu antar att det verkligen är ett träd, och inte har skumma loopar, eller dubletter inne i strukturen, så kan vi dra slutsatsen att varje sista element i "tråden" för varje input måste vara samma, annars inga artiklar, så då returnerar vi det.
3. Annars går vi ner ett steg i taget i varje tråd. Så fort någon av trådarna avviker så vet vi att föregående steg var den lägsta som var gemensam.


Svara

Sv:Artikelträd och SQL

Postades av 2008-05-27 12:17:42 - Stefan Johansson

hej!

Ajaj... "grafen" är inte rätt. nu är den dock uppdaterad.

I databasen finns en tabell som heter TN_ARTICLES som innehåller alla artiklar som finns i systemet. Fältet OBJECT_ID i denna tabell ger alla artiklar ett unikt id.

I databasen finns också en tabell som heter TDM_LINKS_00676. I denna tabell finns fälten OBJECT_ID, CLASS_ID, OBJECT_ID1, CLASS_ID1, OBJECT_ID2, CLASS_ID2 och ett gäng andra fält. OBJECT_ID är bara ett id fält för var rad i denna tabell. OBJECT_ID1 är en artikels id nummer och OBJECT_ID2 är också en artikels id.

Artikelträdet är skapat genom att object_id1 beskriver en huvudnod och object_id2 är en barnnod till denna huvudnod. Det är dessa tre som finns med i "grafen"; ObjectId (OBJECT_ID), ParentId (OBJECT_ID1) och ChildId (OBJECT_ID2).

Strukturen är en IBM (enovia smarteam) skapelse och man får anta att det finns logik som ser till att det inte skapas loopar....

/tack


Svara

Sv: Artikelträd och SQL

Postades av 2008-05-27 12:59:50 - Niklas Jansson

Jepp, men då är min algoritm korrekt, om än långsam. Ska detta göras många gånger, eller som del av en vanlig utsökning?

Som sagt tror jag inte det finns något vettigt sätt att i standard sql lösa det, utan något man bör lösa i kod.
pseudo:

<code
list<int> get_parent_string(obj_id)
{
if(obj_id == null){
return [null];
}
else{
parent = sql("SELECT Parent FROM tbl WHERE Child = ?", obj_id);
return get_parent_string(parent) + obj_id;
}
}

int get_common_parent(input_id)
{
lists l;
for each id in input_id
l[id] = get_parent_string(id);

for(depth = 0 to max)
if not all l[*, depth] is identical return l[any, depth-1];
}
</code>

Hänger du med?


Svara

Sv:Artikelträd och SQL

Postades av 2008-05-27 13:20:53 - Niklas Jansson

Jävlar, det var ju knepigare, det här är ju inget äkta träd, det är ju en DAG, en directed acyclic graph. Men det verkar fortfarande inte vara helt rätt i bilden, i så fall kan det ju inte finnas flera ObjectID.

Jag tror du kan använda samma grundprincip, men att du får bygga träd nerifrån, och sen göra mer komplicerade jämförelser, alternativt bara ta alla tänkbara varianter.

Annars skulle man kunna tänka sig en variant i stil med ett förberedelsesteg:
1. För ett givet ID, räkna ut alla nivåer som det kan ligga på. 1180 SV är bara 2, men FE0067 är alltså både 2 och 3.
2. En gemensam parent till alla input har bara _en_ viss nivå. Så börja med alla noder på lägsta nivån. Om vi har FE0067 och 1180SV så ser vi att den absolut lägsta nivån är 3.
3. Eftersom inte alla input har något på den nivån (alltså 1180SV har ingen på nivå 3) kan inte en gemensam parent ligga på nivå 3.
4. Ta varje nod som ligger på nivå 3 (bara ena FE0067), leta upp dess parentnod (1080SV). Nu har vi två input med vardera två noder, och alla noder ligger på samma nivå.

Sen får man gå uppåt med alla noder, jämföra alla kombinationer, och så fort man får en match mellan alla input tar man bort alla inblandade noder (som är samma) och lägga till den just borttagna noden till "nuvarande lista".


Ytterligare en variant (och jag lutar nog mest mot den nu) är att göra sökning uppåt, precis som i ursprungsförslaget, och "färga" alla ingående noder med inputid. Sen letar man igenom trädet efter de noderna som har alla inputid och ligger längst ner.


Svara

Sv: Artikelträd och SQL

Postades av 2008-05-27 13:48:43 - Martin Adrian

I SQLServer skulle man kanske kunna lösa det så här:

Vi tar först fram en fråga som ger som resultat en tabell bestående av
nod, förälder, avstånd

(avstånd är avståndet mellan nod och förälder)

Därefter hittar vi de poster som har samma förälder med minsta möjliga summa av avstånd, där alla valda noder finns med.

Skulle kunna se ut så här:
(Skriver direkt från huvudet så är säkert nåt jag glömt)

-- Skapa fråga med node, parent, distance
WITH NodeParentDist (node, parent, distance) AS (
-- Första nivån (alla noder som har en förälder)
SELECT node, parent, 1
FROM nodes
WHERE node <> parent
UNION ALL
-- För varje på tidigare nivå, hämta förälderns förälder
SELECT leaf.node, parents.parent, leaf.distance + 1
FROM nodes AS parents INNER JOIN
NodeParentDist As leaf ON leaf.parent = parents.node AND parents.node <> parents.parent
),
-- Hämta summan och antalet för varje förälder
SumCount (parent, NodeCount, DistanceSum) AS (
SELECT parent, Count(node), Sum(distance)
FROM NodeParentDist
WHERE node IN (list of nodes)
GROUP BY parent
)
-- Äntligen kan vi hämta den gemensamma föräldern
SELECT TOP 1 parent
FROM SumCount
WHERE NodeCount = (antalet noder vi söker efter)
ORDER BY DistanceSum ASC


Svara

Sv: Artikelträd och SQL

Postades av 2008-05-28 09:53:21 - Stefan Johansson

niklas:
Sökningen kommer inte göras särskilt ofta. I nuläget finns det en kille som manuellt kollar på olika bottom-up träd för matchningar. Eftersom detta är väldigt osmidigt görs kanske maximalt 10 sådana på en månad...

Du har rätt... suck. Ja det är kvar ett fel i trädet. Under 1080 SV ska såklart MB0040 ha objectid 4. Alla artiklar har såklart unika objectid.

Ska försöka sätta mig in i era förslag under dagen. Väldigt uppskattat!

Har uppdaterat trädet med korrekta värden www.stefanj.se/articletreenew.pdf


Svara

Sv:Artikelträd och SQL

Postades av 2008-05-30 01:23:20 - Stefan Johansson

det går framåt, men lite sakta pga att jag haft lite hög arbetsbelastning i veckan...

för den intresserade har jag ställt samma fråga även på sqlservercentral, se http://www.sqlservercentral.com/Forums/Topic506823-23-1.aspx.

återkommer.


Svara

Nyligen

  • 18:42 Hvor finder man håndlavede lamper
  • 18:41 Hvor finder man håndlavede lamper
  • 16:36 Allt du behöver veta om keramiskt
  • 16:14 Vem anlitar man egentligen när tak
  • 16:14 Vem anlitar man egentligen när tak
  • 16:13 Vem anlitar man egentligen när tak
  • 11:52 Noen erfaring med uttak hos Mostbe
  • 11:51 Noen erfaring med uttak hos Mostbe

Sidor

  • Hem
  • Bli bonusmedlem
  • Läs artiklar
  • Chatta med andra
  • Sök och erbjud jobb
  • Kontakta oss
  • Studentlicenser
  • Skriv en artikel

Statistik

Antal besökare:
Antal medlemmar:
Antal inlägg:
Online:
På chatten:
4 570 570
27 958
271 741
5 827
0

Kontakta oss

Frågor runt konsultation, rådgivning, uppdrag, rekrytering, annonsering och övriga ärenden. Ring: 0730-88 22 24 | pelle@pellesoft.se

© 1986-2013 PelleSoft AB. Last Build 4.1.7169.18070 (2019-08-18 10:02:21) 4.0.30319.42000
  • Om
  • Kontakta
  • Regler
  • Cookies