jag har en tabell "ProduktGrupper" med kolumnerna Med en enkelt SELECT fråga blir det svårt... nej...men jag håller på att lösa det fixxar lite med den sp:n jag fick tidigare, måste bara ha svar på min nya fråga :-) Hejsan..sql-fråga
PGID (primärnyckel)
Parent (numeric)
Namn (text)
eftersom en grupp kan innehålla undergrupper så är PGID är kopplat till Parent
frågan är hur jag skall få ut en vettig struktur med en select-fråga,
med
SELECT
dbo.ProduktGrupper.Namn, ProduktGrupper_1.Namn
FROM
dbo.ProduktGrupper
INNER JOIN
dbo.ProduktGrupper ProduktGrupper_1 ON dbo.ProduktGrupper.Parent = ProduktGrupper_1.PGID
GROUP BY dbo.ProduktGrupper.Parent, ProduktGrupper_1.Name, dbo.ProduktGrupper.Name
blir det
grupp
grupp
undergrupp
undergrupp
osv...
jag skulle vilja att det var sorterat med
grupp
undergrupp
undergrupp
grupp
undergrupp
grupp
osv...
nån som hänger med??Sv: sql-fråga
Jag har dock hittat en sida i books online som gör en SP som kan lösa problemet, leta där eller kolla på denna sida:
http://www.gladh.nu/asphelp/svar18.html
- MSv: sql-fråga
Sv: sql-fråga
Detta är ett ständigt problem med SQL-Servern, jag tror att gränsen på hur många nivåer går vid 32.. Om du använder ADO så rekomenderar jag att fixa till det rekursiva i koden istället... Denna funktion räknar med att första fältet är ID och andra ParentID:et... Funktionen returnerar en exakt kopia på det recordset som du skickar in + ett fält som heter Level..
Public Function RecordsetRecursive(ByVal recOriginal As ADODB.Recordset, ByVal lngStartID As Long, ByVal bolRoot As Boolean) As ADODB.Recordset
On Error Resume Next
Dim recCopy As New ADODB.Recordset, fldField As ADODB.Field, arrRecursive As Variant, lngCounter As Long
Call recOriginal.MoveFirst
For Each fldField In recOriginal.Fields
Call recCopy.Fields.Append(fldField.Name, fldField.Type, fldField.DefinedSize)
recCopy.Fields(fldField.Name).NumericScale = fldField.NumericScale
recCopy.Fields(fldField.Name).Precision = fldField.Precision
Next
Call recCopy.Fields.Append("Level", adInteger)
Call recCopy.Open
arrRecursive = recOriginal.GetRows(, , Array(0, 1))
If Err.Number = 0 Then
Do While lngCounter <= UBound(arrRecursive, 2)
If lngStartID = 0 Then
If arrRecursive(1, lngCounter) = 0 Then
If bolRoot Then
Call Addchild(lngCounter, 0, recOriginal, recCopy)
End If
Call Findchilds(arrRecursive, arrRecursive(0, lngCounter), 1, recOriginal, recCopy)
End If
Else
If arrRecursive(0, lngCounter) = lngStartID Then
If bolRoot Then
Call Addchild(lngCounter, 0, recOriginal, recCopy)
End If
Call Findchilds(arrRecursive, arrRecursive(0, lngCounter), 1, recOriginal, recCopy)
Exit Do
End If
End If
lngCounter = lngCounter + 1
Loop
Call recCopy.MoveFirst
End If
Set RecordsetRecursive = recCopy
End Function
Private Sub Findchilds(arrRecursive As Variant, ByVal lngParentID As Long, ByVal lngLevel As Long, recOriginal As ADODB.Recordset, recCopy As ADODB.Recordset)
Dim lngCounter As Long
Do While lngCounter <= UBound(arrRecursive, 2)
If lngParentID = arrRecursive(1, lngCounter) Then
Call Addchild(lngCounter, lngLevel, recOriginal, recCopy)
Call Findchilds(arrRecursive, arrRecursive(0, lngCounter), lngLevel + 1, recOriginal, recCopy)
End If
lngCounter = lngCounter + 1
Loop
End Sub
Private Sub Addchild(ByVal lngRow As Long, ByVal lngLevel As Long, recOriginal As ADODB.Recordset, recCopy As ADODB.Recordset)
Dim fldField As ADODB.Field
Call recOriginal.Move(lngRow, 1)
Call recCopy.AddNew
recCopy("Level") = lngLevel
For Each fldField In recOriginal.Fields
If Not IsNull(fldField.Value) Then
recCopy(fldField.Name) = fldField.Value
End If
Next
Call recCopy.Update
End Sub
Micke