Как создать идентификатор для простой сортировки в SQL Server? - PullRequest
2 голосов
/ 25 июня 2010

Я создаю веб-сайт, и у меня возникают проблемы при создании родительского / дочернего дерева, например:

Page 1
---Sub page 1
------Sub page 1 - 1
Page 2
Page 3
---Sub page 3
------Sub page 3 - 1
------Sub page 3 - 2

Если я использую UID, невозможно написать t-sql "ORDER BY", чтобы сделатьдерево.Я имею в виду функцию, которая может генерировать идентификатор (varchar), такой как:

001000000
---001001000
------001001001
002000000
003000000
---003001000
------003001001
------003001002

Ответы [ 4 ]

3 голосов
/ 25 июня 2010

Я бы пропустил пользовательский идентификатор и сохранил бы родительские / дочерние отношения в базе данных. Затем используйте рекурсивный запрос для построения вашего дерева.

2 голосов
/ 25 июня 2010

Изучите модель вложенных множеств для иерархий.У Джо Селко есть книга , которая охватывает это в дополнение к другим способам моделирования деревьев и иерархий в SQL.С моделью вложенного множества у вас будет что-то вроде этого:

CREATE TABLE Tree_Nodes
(
    lft     INT         NOT NULL,
    rgt     INT         NOT NULL,
    name    VARCHAR(40) NOT NULL,
    CONSTRAINT PK_Tree_Nodes PRIMARY KEY CLUSTERED (lft, rgt)
)
INSERT INTO Tree_Nodes (lft, rgt, name)
SELECT 1, 6, 'Page 1' UNION ALL
SELECT 2, 5, 'Sub page 1' UNION ALL
SELECT 3, 4, 'Sub page 1 - 1' UNION ALL
SELECT 7, 8, 'Page 2' UNION ALL
SELECT 9, 16, 'Page 3' UNION ALL
SELECT 10, 15, 'Sub page 3' UNION ALL
SELECT 11, 12, 'Sub page 3 - 1' UNION ALL
SELECT 13, 14, 'Sub page 3 - 2'

Затем, чтобы получить результат, который вы пытаетесь получить, просто:

0 голосов
/ 25 июня 2010

Может быть, вы можете сохранить родительский идентификатор в таблице и вместо того, чтобы пытаться сделать это в таблице, просто вернуть строки и использовать рекурсию для построения дерева следующим образом: для оптимизации после первого запуска вы можете сохранитьпорядок табуляции и порядок сортировки в свойстве, которое вы назначаете при первом рекурсивном прогоне в вашем классе данных.Вот пример ...

class Program
{


    static void Main(string[] args)
    {
        Program program = new Program();

        List<Data> rows = new List<Data>();
        program.CreateData(rows);

        Console.WriteLine("Data ...");
        program.ShowData(rows);
        Console.WriteLine("");

        Console.WriteLine("Data as tree ...");
        program.ShowDataAsTree(rows);
        Console.WriteLine("");

    }


    public void ShowData(List<Data> rows)
    {
        foreach (Data row in rows)
        {
            Data parent = rows.Find(item => item.Id == row.Parent);
            Console.WriteLine(String.Format("Name = {0}, Parents Name = {1}", row.Text, parent == null ? "" : parent.Text));
        }
    }

    public void ShowDataAsTree(List<Data> rows)
    {
        rows.Sort((item1, item2) => item1.Text.CompareTo(item2.Text));
        ShowDataSortedWrk(rows, Guid.Empty, 0);
    }

    public void ShowDataSortedWrk(List<Data> rows, Guid parentId, int tab)
    {
        foreach (Data row in rows)
        {
            if (row.Parent == parentId)
            {
                for (int i = 0; i < tab; i++)
                {
                    Console.Write("\t");
                }

                Console.WriteLine(row.Text);

                ShowDataSortedWrk(rows, row.Id, tab + 1);
            }
        }
    }

    public void CreateData(List<Data> rows)
    {
        Data alice = new Data(Guid.Empty, "Alice");
        rows.Add(alice);

        Data eric = new Data(Guid.Empty, "Eric");
        rows.Add(eric);

        Data mike = new Data(alice.Id, "Mike");
        rows.Add(mike);

        rows.Add(new Data(mike.Id, "Mark"));
        rows.Add(new Data(eric.Id, "Jane"));
        rows.Add(new Data(alice.Id, "Emma"));
        rows.Add(new Data(mike.Id, "Fred"));
        rows.Add(new Data(alice.Id, "Perry"));
        rows.Add(new Data(eric.Id, "Julie"));
        rows.Add(new Data(eric.Id, "Paul"));
    }
}

public class Data
{
    public Data(Guid parent, string text)
    {
        this.Id = Guid.NewGuid();
        this.Parent = parent;
        this.Text = text;
    }

    public Guid Id
    {
        get;
        set;
    }


    public Guid Parent
    {
        get;
        set;
    }


    public String Text
    {
        get;
        set;
    }
}
0 голосов
/ 25 июня 2010

Для веб-страниц это просто использовать URL для этого.Идея Тоби тоже в порядке, но, вероятно, она сложнее, чем вам нужно (хотя я на самом деле делаю то, что он вам говорит, в другом приложении, поэтому я не оспариваю это при правильных обстоятельствах).Ваша схема на самом деле тоже будет работать.

Однако, зачем вам функция, которая сделает это за вас?В плоском плане вы можете с радостью позволить AUTO_INCREMENT сделать вашу работу за вас;но в иерархии вы хотите решить, куда идти, и никакая функция не может сделать это за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...