用于排序多级类别数据的mysql查询

时间:2011-02-15 11:13:40

标签: mysql

我有表category

id, parent_id, title, ordering (ordered according to same level of hierarchy by parent_id) 

看看这张图片:

This is my table data's hierarchy level, the number beside the cat name is value of ordering and the level of hierarchy is according to parent_id value starting 0-4

我需要一个查询,它将提供以下输出:

1. cat A
2. cat C
3. cat D
4. cat B
5. cat E
6. cat F
7. cat H
8. cat K
9. cat I
10. cat J
11. cat G

3 个答案:

答案 0 :(得分:2)

请使用此查询 - 这可能会对您有所帮助。

此查询适用于SQL Server 2005。

DECLARE @PID1 VARCHAR(10),
        @CID1 VARCHAR(10),
        @CATNAME VARCHAR(100),
        @ORDERING VARCHAR(100)

IF object_id('tempdb..#TEMP') IS NOT NULL
BEGIN
    DROP TABLE #TEMP
END

CREATE TABLE #TEMP (Product VARCHAR(100), c2 VARCHAR(100))

DECLARE CCAT1 CURSOR FOR
     SELECT cat_id, cat_name, parent_id 
     FROM product

OPEN CCAT1

FETCH FROM CCAT1 INTO @CID1, @CATNAME, @PID1

WHILE @@FETCH_STATUS = 0
BEGIN 
    SET @ORDERING = @CATNAME  

    IF EXISTS (SELECT cat_id FROM product WHERE cat_id = @PID1) 
    BEGIN    -- IF PARENT EXIST CHECK ITS PARENT AGAIN 2 LEVEL
        DECLARE @PID2 VARCHAR(10),
                @CID2 VARCHAR(10),
                @CATNAME2 VARCHAR(100)

        DECLARE CCAT2 CURSOR FOR
            SELECT cat_id, parent_id, cat_name 
            FROM product 
            WHERE cat_id = @PID1

        OPEN CCAT2

        FETCH FROM CCAT2 INTO @CID2, @PID2, @CATNAME2

        WHILE @@FETCH_STATUS = 0
        BEGIN 
            SET @ORDERING = @CATNAME2 + @ORDERING

            IF EXISTS (SELECT cat_id FROM product WHERE cat_id = @PID2)
            --IF PARENT EXISTS CHECK ITS PARENT AGAIN //3 LEVEL
            BEGIN    --SET @ORDERING=@ORDERING+@PID2
                DECLARE @PID3 VARCHAR(10), 
                        @CID3 VARCHAR(10),
                        @CATNAME3 VARCHAR(100)

                DECLARE CCAT3 CURSOR FOR
                    SELECT cat_id, parent_id,cat_name 
                    FROM product 
                    WHERE cat_id = @PID2

                OPEN CCAT3
                FETCH FROM CCAT3 INTO @CID3, @PID3, @CATNAME3

                WHILE @@FETCH_STATUS = 0
                BEGIN 
                    SET @ORDERING=@CATNAME3 + @ORDERING

                    IF EXISTS (SELECT cat_id FROM product WHERE cat_id = @PID3)
                    BEGIN --SET @ORDERING=@ORDERING+@PID2
                        DECLARE @PID4 VARCHAR(10),
                                @CID4 VARCHAR(10),
                                @CATNAME4 VARCHAR(100)

                        DECLARE CCAT4 CURSOR FOR
                             SELECT cat_id, parent_id,cat_name 
                             FROM product 
                             WHERE cat_id = @PID3

                        OPEN CCAT4

                        FETCH FROM CCAT4 INTO @CID4, @PID4, @CATNAME4

                        WHILE @@FETCH_STATUS = 0
                        BEGIN 
                            SET @ORDERING = @CATNAME4 + @ORDERING

                            IF EXISTS(SELECT cat_id FROM product WHERE cat_id=@PID4)
                                BEGIN --SET @ORDERING=@ORDERING+@PID2
                                    DECLARE @PID5 VARCHAR(10),@CID5 VARCHAR(10),@CATNAME5 VARCHAR(100)
                                    DECLARE CCAT5 CURSOR for
                                    Select cat_id, parent_id,cat_name from product WHERE cat_id=@PID4
                                    OPEN CCAT5
                                    FETCH FROM CCAT5 INTO @CID5,@PID5,@CATNAME5
                                    WHILE @@FETCH_STATUS=0
                                    BEGIN 
                                        SET @ORDERING=@CATNAME5 + @ORDERING
                                        IF exists(SELECT cat_id FROM product WHERE cat_id=@PID5)
                                        BEGIN
                                            PRINT 'END'
                                        END
                                        FETCH FROM CCAT5 INTO @CID5,@PID5,@CATNAME5
                                    END
                                    CLOSE CCAT5
                                    DEALLOCATE CCAT5
                                END--END IF PARENT EXIST CHECH ITS PARENT AGAIN
                            FETCH FROM CCAT4 INTO @CID4,@PID4,@CATNAME4
                        END
                        CLOSE CCAT4
                        DEALLOCATE CCAT4
                    END--END IF PARENT EXIST CHECH ITS PARENT AGAIN
                    FETCH FROM CCAT3 INTO @CID3,@PID3,@CATNAME3
                END
                CLOSE CCAT3
                DEALLOCATE CCAT3
                END--END IF PARENT EXIST CHECH ITS PARENT AGAIN 2
        FETCH FROM CCAT2 INTO @CID2,@PID2,@CATNAME2
        END
        CLOSE CCAT2 
        DEALLOCATE CCAT2

    END--END IF PARENT EXIST CHECH ITS PARENT AGAIN 1
    --SELECT @ORDERING
    INSERT INTO #TEMP VALUES(@CATNAME,@ORDERING)
    FETCH FROM CCAT1 INTO @CID1,@CATNAME,@PID1
END

CLOSE CCAT1 
DEALLOCATE CCAT1

set nocount on

SELECT Product FROM #TEMP ORDER BY c2

答案 1 :(得分:0)

你不能解压缩整个表并构建二叉树吗?然后使用深度优先预先遍历来遍历它? http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal

答案 2 :(得分:0)

我已将表category命名为。我已经放置了上面提到的类别和子类别。我使用的字段是cat_id,category,parent_cat_id

我准备了以下查询:

SELECT * FROM
  (
  SELECT 0 AS parent_id,'' AS parent,cat_id AS category_id,category AS category FROM categories WHERE parent_cat_id=0
  UNION
  SELECT cat.cat_id AS parent_id,cat.category AS parent,chd.cat_id AS category_id,chd.category AS category FROM categories chd
  INNER JOIN categories cat ON cat.cat_id=chd.parent_cat_id
  ) AS t
ORDER BY concat(t.parent,t.category)

虽然它仍然不准确,但我希望这可以帮助你继续前进