2013-06-29 36 views
1

我在創建SQL查詢以顯示一個表中的類別和子類別方面遇到了很多麻煩。我有以下欄目:按順序顯示類別和子類別

category_id 
category_name 
category_parent 
category_order 

基本上我想產生的結果是這樣的

parent category 1 
sub category 1 
sub category 2 
parent category 2 
sub category 1 
sub category 2 
sub category 3 
parent category 3 
sub category 1 

如果category_order設置爲0,類別或子類別應進行排序依據他們創建的順序。爲此,我計劃按ID排序。

如果可能我想使用一個聯合,以便他們已經在秩序,我只需要循環。任何人都可以幫我建立一個查詢。

其實我已經有一個使用JOIN,但結果並不像我想要的那樣精確。

這是我以前的查詢:

SELECT 
fcat.id fcat_id, 
fcat.name fcat_name, 
fcat.order fcat_order, 
fcat.parent fcat_parent, 
fsub.id fsub_id, 
fsub.name fsub_name, 
fsub.order fsub_order, 
fsub.parent fsub_parent 
FROM forum_categories AS fcat 
LEFT OUTER JOIN forum_categories AS fsub ON fcat.id = fsub.parent 
ORDER BY ISNULL(fcat.order) ASC, fcat.id ASC, ISNULL(fsub.order) ASC, fsub.id ASC 

但是,它並沒有在子類,因爲父類別和子類別排序加盟。我的查詢只對父項進行排序。

+0

你可以發佈你的連接查詢?它有什麼問題? –

+0

樹的深度僅限於2,如你的例子? – TMS

+0

而且,樹的深度有限嗎? – TMS

回答

2

當樹的深度只限於2:

select c1.*, 
     c2.*, 
     if (c2.category_parent is NULL, "parent category", "sub category") as text 
from cat c1 left join cat c2 
    on c1.category_id = c2.category_parent 
order by c1.category_id, c2.category_id 

您可以使用條件c2.category_parent is NULL測試類別的水平。

4

我認爲排序是這裏有趣的部分。特別是,一個類別內的排序很有趣。我做了說明這是一個小提琴:http://sqlfiddle.com/#!8/78059/3

這裏的查詢:

select * from (
    select c.*, 
    coalesce(nullif(c.parent, 0), c.id) as groupID, 
    case when c.parent = 0 then 1 else 0 end as isparent, 
    case when p.`order` = 0 then c.id end as orderbyint 
    from category c 
    left join category p on p.id = c.parent 
) c order by groupID, isparent desc, orderbyint, name 

我們可以標註每個分類均具有無論是父母還是不行。然後我們可以將類別分組。在每個組內,訂單取決於父訂單。在這裏,我在parent.order爲0時根據ID進行訂單。如果不是0,則orderbyint爲空,然後我們按name排序。

+0

我喜歡你的答案。如果我沒有得到這個錯誤,我會使用###在'c as附近使用正確的語法(選擇c。*,coalesce(c.parent,c.id)作爲groupID,case when c.par'在第1行 – user949000

+0

@ user949000對不起,我沒有看到數據庫版本,我將修復與mysql的小提琴並讓你知道 –

+0

@ user949000我已經編輯我的答案與MySQL的工作。更新。 –

0

我有同樣的問題,並測試了很多示例或Tomas和JTseng解決方案。這些缺少數字排序或子類別排序。我修改JTseng查詢,它是確定(對我來說)現在,這種方式:

SELECT c.*, 
    CASE WHEN isnull(is_par.cat_id) THEN c.cat_sort_order ELSE is_par.cat_sort_order END as sort_order, 
    CASE WHEN isnull(is_par.cat_id) THEN c.cat_id ELSE is_par.cat_id END as catid , 
    CASE WHEN isnull(is_par.cat_id) THEN 0 ELSE c.cat_sort_order END as subcat_order 
FROM `category` c 
LEFT JOIN `category` is_par ON is_par.cat_id = c.cat_parent_id 
ORDER BY sort_order , catid, subcat_order 

我寫了測試,其中排序是通過創建一個連接字符串,由三根弦的的解決方案後,該解決方案:第一個是一個父類別的主排序順序,第二個字符串用於對父類別及其子類進行分組,第三個字符串用於根據子訂單排序父類及其子級(並將父貓放在第一位,它們被賦予一個虛擬子類別順序設置爲0)。但是這個字符串排序,給了一個字母順序,而不是一個數字。因此,以JTseng這樣的方式將字符串轉換爲額外的數字字段:

  • 第一個CASE WHEN用於檢測類別是否爲父類。如果它是父級,則保留父級排序順序,如果它是子類別,則它的排序順序將由父級的排序順序替換
  • 第二個CASE WHEN用於替換順序中的子類別id (這相當於JTseng GROUPID)
  • 第三CASE WHEN用於設置0到父子排序順序和保持子貓排序順序

要使LEFT JOIN動作的視圖,只是執行該在您的phpMyAdmin頁面中查詢:

SELECT c.cat_id as ccatid,c.cat_sort_order as ccatsortorder, is_par.cat_id as isparcatid,is_par.cat_parent_id as ispar_catparentid,is_par.cat_sort_order as isparcatsortorder, 
    CASE WHEN isnull(is_par.cat_id) THEN c.cat_sort_order ELSE is_par.cat_sort_order END as sort_order, 
    CASE WHEN isnull(is_par.cat_id) THEN c.cat_id ELSE is_par.cat_id END as catid, 
    CASE WHEN isnull(is_par.cat_id) THEN 0 ELSE c.cat_sort_order END as subcat_order 
FROM `category` c 
LEFT JOIN `category` is_par ON is_par.cat_id = c.cat_parent_id 
0

我發現實現它的方式。它按照層次結構和字母順序排列。

首先,我把看到的例子所需要的SQL:

CREATE TABLE IF NOT EXISTS `categories` (
    `category_id` int(11) NOT NULL AUTO_INCREMENT, 
    `category_parent` int(11) NOT NULL, 
    `category_name` varchar(100) COLLATE latin1_spanish_ci NOT NULL, 
    PRIMARY KEY (`category_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci; 

現在快速插入到有結果:

INSERT INTO categoriescategory_idcategory_parentcategory_name)VALUES ( 1,0,'Category number 1'), (2,0,'Category number 2'), (3,0,'Category number 3'), (4,0,'Category number 4'),(6,0), (7,2,'第2類的第一子類別'), (8,2',第二子類別), (9,2,'第3類子類別(必須首先出現,因爲字母順序)'), (10,1,'第1類別的第1子類別'), (11 ,1,'Ans second category of category number 1(has to first first because alphabetic order)');

而SQL語句:

SELECT category_id,category_parent,category_name, 
(CASE 
    WHEN category_parent=category_id OR category_parent=0 THEN category_id 
    WHEN category_parent<>category_id THEN category_parent 
END) AS 'the_parent' 
FROM categories ORDER BY the_parent ASC, category_parent ASC, category_name ASC 

我希望這是有用的

0

這就是我的回答對的3子類別深度1級,級別2和3級

SELECT 
    main.id AS main_id, 
    level1.id AS level1_id, 
    level2.id AS level2_id, 
    level3.id AS level3_id 
FROM 
    categories AS main 
LEFT OUTER JOIN categories AS level1 ON level1.parent_id = main.id 
LEFT OUTER JOIN categories AS level2 ON level2.parent_id = level1.id 
LEFT OUTER JOIN categories AS level3 ON level3.parent_id = level2.id 
WHERE 
    main.parent_id = "ID-OF-MAIN-CATEGORY" 
ORDER BY 
    main_id, 
    level1_id, 
    level2_id, 
    level3_id 

您查詢會看起來類似於此(示意圖)

enter image description here

希望幫助