2016-01-15 7 views
1

У меня есть таблица CATEGORY, где у меня есть категории. У каждой категории могут быть подкатегории (или дети). Если это основная категория parent = 0, в противном случае она равна родительскому идентификатору. Например,Поиск иерархических данных

ID |Category |Parent 
    1 Fruit  0 
    2 Apple  1 
    3 Orange  1 
    4 Vegetable 0 
    5 Onion  4 
    6 Tomato  4 
    7 Red Apple 2 
    8 Green Apl 2 

Таким образом, используя код, который я могу создать следующий список

Fruit 
    - Apple 
    - Red Apple 
    - Green Apl 
    - Orange 
Vegetable 
    - Onion 
    - Tomato 

У меня есть другие SOLD_ITEMS таблицы, где я использую CATEGORY.ID.

Вопросы

1) Может кто-то помочь мне выполнить запрос из SOLD_ITEMS WHERE CATEGORY.ID равно Фрукты или любой из его? Порожденных

Возможно, у меня есть возможность кодировать его за пределами SQL и генерировать строку запроса, например: WHERE CATEGORY.ID IN (1,2,3,4,7,8), мне просто интересно, есть ли альтернатива он в SQL-запросе

2) Использование SQL, есть ли запрос, в котором я могу получить верхнюю часть самого родителя с указанием CATEGORY.ID? например Для 8 (Green Apl) будет 1. Для 4 (Овощ) будет 4.

Возможно, я затрудняюсь с использованием SQL, я не могу. Я пока не настолько эффективен с использованием SQL.

+0

Ваш вопрос с тремя различными СУБД. Возможное решение зависит от конкретной СУБД, которую вы используете. –

+0

Извините, Энди Корнеев, я использую базу данных VB.net и MS-Access –

+0

Я бы настоятельно рекомендовал читать и внедрять модель Nested Set для иерархии в базах данных. https://en.wikipedia.org/wiki/Nested_set_model – GavinP

ответ

0

Я прочитал о модели вложенного набора, хотя запросы будут упрощены, что добавляет сложности INSERT, UPDATE, change parent и т. Д. Я должен был бы гарантировать, что каждое изменение в Category_ID будет отражено в текущих записях, связанных с Category_ID ,

Итак, я решил использовать VB.net TreeView1. Это может быть не самым лучшим ответом, но он прост в реализации

Sub Load_Cateogries(treeview1 As TreeView) 
    Dim ds As New DataSet 
    Dim sSQL As String 

    treeview1.Nodes.Clear() 

    Dim cmd As OleDb.OleDbCommand = New OleDb.OleDbCommand 

    sSQL = "SELECT * FROM Product_Categories WHERE Parent=0" 
    cmd.CommandText = sSQL 
    If Query_DB(cmd, ds) Then 
     For i = 0 To ds.Tables(0).Rows.Count - 1 
      Dim TNode As TreeNode 

      TNode = treeview1.Nodes.Add(ds.Tables(0).Rows(i).Item("Category").ToString) 
      TNode.Tag = ds.Tables(0).Rows(i).Item("Category_ID").ToString 

      Load_Category(TNode.Tag, TNode) 
     Next 
    End If 

    treeview1.ExpandAll() 
End Sub 

Sub Load_Category(iParent As Integer, tn As TreeNode) 
    Dim ds As New DataSet 
    Dim sSQL As String 

    Dim cmd As OleDb.OleDbCommand = New OleDb.OleDbCommand 

    sSQL = "SELECT * FROM Product_Categories WHERE Parent=" & iParent 
    cmd.CommandText = sSQL 
    If Query_DB(cmd, ds) Then 
     For i = 0 To ds.Tables(0).Rows.Count - 1 
      Dim TNode As TreeNode 

      TNode = tn.Nodes.Add(ds.Tables(0).Rows(i).Item("Category").ToString) 
      TNode.Tag = ds.Tables(0).Rows(i).Item("Category_ID").ToString 

      Load_Category(TNode.Tag, TNode) 
     Next 
    End If 

    ds.Dispose() 
End Sub 

и запроса для категории и ее Чайлдс может быть завершен в "SELECT * FROM Product_Categories WHERE Category_ID IN (" & Get_Parent_and_Childs() & ")" для selectednode в этом случае, позволяя управление разбирайтесь (функция TreeView1.Nodes.Find() становится полезной, если вы хотите, чтобы определенный родитель не позволял пользователю выбирать его).

Function Get_Parent_and_Childs() As String 
    Dim sTag As String = "" 

    If TreeView1.SelectedNode IsNot Nothing Then 
     sTag = TreeView1.SelectedNode.Tag 
     Get_Child(sTag, TreeView1.SelectedNode) 
    End If 

    Return sTag 
End Function 

Sub Get_Child(ByRef sTag As String, nParent As TreeNode) 
    For Each n As TreeNode In nParent.Nodes 
     sTag &= ", " & n.Tag 
     Get_Child(sTag, sDesc, n) 
    Next 
End Sub 

Благодарим за помощь!

Смежные вопросы