2013-06-29 3 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.

если возможно, я хочу использовать UNION, чтобы они уже были в порядке, и мне просто нужно было бы петли. может кто-нибудь помочь мне построить запрос для этого.

Фактически у меня уже есть тот, который использует 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

Можете ли вы опубликовать ваш JOIN запрос? Что случилось с этим? –

+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. Если это не 0, то orderbyint имеет значение null, а затем мы сортируем его по name.

+0

Мне нравится, когда вы отвечаете. Я бы использовал это, если я не получу эту ошибку ### правильный синтаксис для использования рядом с 'c as (выберите c. *, Coalesce (c.parent, c.id) как groupID, если 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 КОГДА существует, чтобы определить, является ли категория родительской или нет.Если он является родителем, сохраняется порядок сортировки родителя, если он является подкатегорией, его порядок сортировки заменяется порядком сортировки родителя
  • Второй CASE WHEN используется для замены в способе, идентификатор подкатегории по его идентификатору родительской категории (это эквивалентно JTseng GroupID)
  • Третий случай, когда используется для установки от 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 categories (category_id, category_parent, category_name) ЗНАЧЕНИЯ (1, 0, 'Категория № 1'), (2, 0, 'Категория номер 2'), (3, 0, 'Категория номер 3'), (4, 0, 'Категория номер 4'), (5, 0, 'Категория номер 5'), (6, 0, 'Категория номер 6'), (7, 2, 'Первая подкатегория категории 2'), (8, 2, 'Вторая подкатегория категории 2 '), (9, 2,' И третья подкатегория категории 2 (должна появиться первой, поскольку алфавитный заказ) '), (10, 1,' Первая подкатегория категории 1 '), (11 , 1, 'Ans second Подкатегория категории номер 1 (должна появиться сначала, потому что алфавитный порядок)');

И 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 подкатегорий LEVEL1, level2 и level3

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

надежда, что помогает

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