Сортиране на категории и подкатегории от 1 таблица?

streleca_stz

Registered
Здравейте!

Опитвам се да сортирам по този начин резултати от таблица, в която се съдържат както главните категории, така и подкатегориите. Но не мога нещо да се справя.. Някой от вас има ли предложение как би могло да стане сортирането?
Код:
Главна категория
     Подкатегория 1
     Подкатегория 2
Главна Категория 2
     Подкатегория 1
     Подкатегория 2
     Подкатегория 3
и т.н.
 
eLite каза:
А какви са ти колоните?
CREATE TABLE IF NOT EXISTS `items_categories` (
`cat_id` int(12) NOT NULL AUTO_INCREMENT,
`category` varchar(100) NOT NULL,
`subCategory` varchar(100) NOT NULL,
PRIMARY KEY (`cat_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=25 ;

Примерен запис:
1, Главна Категория 1, NULL (т.е. празно седи)
2, 1, Подкатегория 1
3, 1, Подкатегория 2
4, 1, Подкатегория 3
5, Главна Категория 2, NULL
6, 5, Подкатегория 1
7, 5, Подкатегория 2
 
Имах същия проблем онзи ден, реших си го с този код:

PHP:
$sql = mysql_query("SELECT * FROM db ORDER BY category ASC");
$cat = ""; //initialize $cat variable 
while($row = mysql_fetch_assoc($sql)){ 
if($row['category'] != $cat) echo "<h3>".$row['category']."</h3>\r\n"; 
echo "<p>".$row['value']."</p>\r\n"; 
$cat = $row['category']; 
}

Напаснете го според вашия код, ще стане, гарантирам. :)
 
dijon каза:
Имах същия проблем онзи ден, реших си го с този код:

PHP:
$sql = mysql_query("SELECT * FROM db ORDER BY category ASC");
$cat = ""; //initialize $cat variable 
while($row = mysql_fetch_assoc($sql)){ 
if($row['category'] != $cat) echo "<h3>".$row['category']."</h3>\r\n"; 
echo "<p>".$row['value']."</p>\r\n"; 
$cat = $row['category']; 
}

Напаснете го според вашия код, ще стане, гарантирам. :)
При мен не става, защото показва id-то на главната категории, както и факта, че ако да речем добавя нова подкатегория към първата главна категория, отива под всички главни категории, а не при останалите подкатегории от тази главна категория (дано да ми схванете смисъла.. ;д)
 
Защо не пробваш с две таблици - едната да съдържа id на подкатегория, подкатегория, главна категория.
В другата таблица имаш айдито на подкатегория, ид на съдържание, съдържание на подкатегория:

Категории:
--------------------------------------------------------------------
|id na podkategoriq | podkategoriq | glavna kategoriq |
--------------------------------------------------------------------

Съдържание на подкатегориите
------------------------------------------------------------------------------------------
|id na podkategoriq | id na sydyrvanie | sydyrvanie na podkategoriqta |
------------------------------------------------------------------------------------------
 
streleca_stz каза:
Примерен запис:
1, Главна Категория 1, NULL (т.е. празно седи)
2, 1, Подкатегория 1
3, 1, Подкатегория 2
Защо тогава е декларирано NOT NULL? Защо subCategory e VARCHAR, kamo e reference на cat_id, koemo e int(12)?

[sql]
DROP TABLE IF EXISTS items_categories;

CREATE TABLE `items_categories` (
`cat_id` INT(12) NOT NULL AUTO_INCREMENT,
`category` varchar(255) NOT NULL DEFAULT '',
`subCategory` INT(12) DEFAULT NULL,
PRIMARY KEY (`cat_id`)
)Engine=MYISAM DEFAULT CHARACTER SET UTF8;

INSERT INTO items_categories VALUES
(1,'Главна Категория 1',NULL),
(2,'Подкатегория 1',1),
(3,'Подкатегория 2',1),
(4,'Подкатегория 3',1),
(5,'Главна Категория 2',NULL),
(6,'Подкатегория 1',5),
(7,'Подкатегория 2',5);
[/sql]
[sql]
SELECT * FROM items_categories
ORDER BY CASE ISNULL(subCategory)
WHEN 1 THEN cat_id
ELSE subCategory
END ASC,
cat_id ASC;
[/sql]
mysql> SELECT * FROM items_categories
-> ORDER BY CASE ISNULL(subCategory)
-> WHEN 1 THEN cat_id
-> ELSE subCategory
-> END ASC,
-> cat_id ASC;
+--------+-----------------------------------+-------------+
| cat_id | category | subCategory |
+--------+-----------------------------------+-------------+
| 1 | Главна Категория 1 | NULL |
| 2 | Подкатегория 1 | 1 |
| 3 | Подкатегория 2 | 1 |
| 4 | Подкатегория 3 | 1 |
| 5 | Главна Категория 2 | NULL |
| 6 | Подкатегория 1 | 5 |
| 7 | Подкатегория 2 | 5 |
+--------+-----------------------------------+-------------+
7 rows in set (0.00 sec)
:)
 
anonimen каза:
Защо не пробваш с две таблици - едната да съдържа id на подкатегория, подкатегория, главна категория.
В другата таблица имаш айдито на подкатегория, ид на съдържание, съдържание на подкатегория:

Категории:
--------------------------------------------------------------------
|id na podkategoriq | podkategoriq | glavna kategoriq |
--------------------------------------------------------------------

Съдържание на подкатегориите
------------------------------------------------------------------------------------------
|id na podkategoriq | id na sydyrvanie | sydyrvanie na podkategoriqta |
------------------------------------------------------------------------------------------
Защото искам да намаля колкото се може повече mysql заявките към сървъра.. :)

koko5 каза:
streleca_stz каза:
Примерен запис:
1, Главна Категория 1, NULL (т.е. празно седи)
2, 1, Подкатегория 1
3, 1, Подкатегория 2
Защо тогава е декларирано NOT NULL? Защо subCategory e VARCHAR, kamo e reference на cat_id, koemo e int(12)?

[sql]
DROP TABLE IF EXISTS items_categories;

CREATE TABLE `items_categories` (
`cat_id` INT(12) NOT NULL AUTO_INCREMENT,
`category` varchar(255) NOT NULL DEFAULT '',
`subCategory` INT(12) DEFAULT NULL,
PRIMARY KEY (`cat_id`)
)Engine=MYISAM DEFAULT CHARACTER SET UTF8;

INSERT INTO items_categories VALUES
(1,'Главна Категория 1',NULL),
(2,'Подкатегория 1',1),
(3,'Подкатегория 2',1),
(4,'Подкатегория 3',1),
(5,'Главна Категория 2',NULL),
(6,'Подкатегория 1',5),
(7,'Подкатегория 2',5);
[/sql]
[sql]
SELECT * FROM items_categories
ORDER BY CASE ISNULL(subCategory)
WHEN 1 THEN cat_id
ELSE subCategory
END ASC,
cat_id ASC;
[/sql]
mysql> SELECT * FROM items_categories
-> ORDER BY CASE ISNULL(subCategory)
-> WHEN 1 THEN cat_id
-> ELSE subCategory
-> END ASC,
-> cat_id ASC;
+--------+-----------------------------------+-------------+
| cat_id | category | subCategory |
+--------+-----------------------------------+-------------+
| 1 | Главна Категория 1 | NULL |
| 2 | Подкатегория 1 | 1 |
| 3 | Подкатегория 2 | 1 |
| 4 | Подкатегория 3 | 1 |
| 5 | Главна Категория 2 | NULL |
| 6 | Подкатегория 1 | 5 |
| 7 | Подкатегория 2 | 5 |
+--------+-----------------------------------+-------------+
7 rows in set (0.00 sec)
:)
Окей, разбрах замисъла, но как би могло да стане изкарването на категориите.. Там по начина по който бях писал по-горе?
 
streleca_stz каза:
Окей, разбрах замисъла, но как би могло да стане изкарването на категориите.. Там по начина по който бях писал по-горе?
Доколкото виждам, ти правиш echo $row['cat_id'].$row['subCategory'].$row['category'] , т.е. разменяш местата на subCategory и category.
Example:
[sql]
SELECT cat_id,
subCategory,
category FROM items_categories
ORDER BY CASE ISNULL(subCategory)
WHEN 1 THEN cat_id
ELSE subCategory
END ASC,
cat_id ASC;
[/sql]
За да се убедиш, че подреждането работи, направи примерно:
[sql]
UPDATE items_categories SET cat_id=9 WHERE cat_id=2;

SELECT cat_id,
subCategory,
category FROM items_categories
ORDER BY CASE ISNULL(subCategory)
WHEN 1 THEN cat_id
ELSE subCategory
END ASC,
cat_id ASC;
[/sql]
mysql> SELECT cat_id,
-> subCategory,
-> category FROM items_categories
-> ORDER BY CASE ISNULL(subCategory)
-> WHEN 1 THEN cat_id
-> ELSE subCategory
-> END ASC,
-> cat_id ASC;
+--------+-------------+-----------------------------------+
| cat_id | subCategory | category |
+--------+-------------+-----------------------------------+
| 1 | NULL | Главна Категория 1 |
| 3 | 1 | Подкатегория 2 |
| 4 | 1 | Подкатегория 3 |
| 9 | 1 | Подкатегория 1 |
| 5 | NULL | Главна Категория 2 |
| 6 | 5 | Подкатегория 1 |
| 7 | 5 | Подкатегория 2 |
+--------+-------------+-----------------------------------+
7 rows in set (0.01 sec)
^^Виждаш, че Подкатегория 1 е отново към Главна Категория 1, въпреки че новото cat_id==9 за тази Подкатегория.
п.п.: данните в тестовата таблица са от предишния ми пост.
:)
 
Ох да.. То ти си ми обяснил всички точно, но кой да глед.... *facepalm*
Обаче не мога да ги изкарам както трябва.. Главните категории се намират в обикновен списък, но под категориите се напират в подсписъци на главният списък.. Как би могло да стане извеждането при такава заявка О.О :idea:
 
Добави желаните html tags b резултата, за да е ясно какво се търси:

+--------+-------------+-----------------------------------+
| cat_id | subCategory | category |
+--------+-------------+-----------------------------------+
| 1 | NULL | Главна Категория 1 |
| 3 | 1 | Подкатегория 2 |
| 4 | 1 | Подкатегория 3 |
| 9 | 1 | Подкатегория 1 |
| 5 | NULL | Главна Категория 2 |
| 6 | 5 | Подкатегория 1 |
| 7 | 5 | Подкатегория 2 |
+--------+-------------+-----------------------------------+
 
koko5 каза:
Добави желаните html tags b резултата, за да е ясно какво се търси:

+--------+-------------+-----------------------------------+
| cat_id | subCategory | category |
+--------+-------------+-----------------------------------+
| 1 | NULL | Главна Категория 1 |
| 3 | 1 | Подкатегория 2 |
| 4 | 1 | Подкатегория 3 |
| 9 | 1 | Подкатегория 1 |
| 5 | NULL | Главна Категория 2 |
| 6 | 5 | Подкатегория 1 |
| 7 | 5 | Подкатегория 2 |
+--------+-------------+-----------------------------------+
До колкото те разбирам искаш да напиша пригледно как искам да изобразя резултатите? :)
HTML:
<ul>
	<li><a href="#">Главна Категория 1</a>
		<ul>
			<li><a href="#">Подкатегория 1</a></li>
			<li><a href="#">Подкатегория 2</a></li>
			<li><a href="#">Подкатегория 3</a></li>
		</ul>
	</li>
	<li><a href="#">Главна Категория 2</a>
		<ul>
			<li><a href="#">Подкатегория 1</a></li>
			<li><a href="#">Подкатегория 2</a></li>
		</ul>
	</li>
</ul>
 
Щом като държиш всичко да е чрез sql (и правилно!) :

[sql]SELECT GROUP_CONCAT('<ul>',CONCAT(GLAVNA,'<ul>',
CASE
ISNULL(SUBCAT)
WHEN 1
THEN ''
ELSE
SUBCAT
END,'</ul></li>'),'</ul>') BLA FROM
(SELECT
CONCAT('<li><a href="#">',A.category,'</a>') GLAVNA,
GROUP_CONCAT('<li>',
CONCAT('<a href="#">',B.category,'</a>'),'</li>'
ORDER BY B.cat_id ASC SEPARATOR '') SUBCAT
FROM (SELECT * FROM items_categories WHERE subCategory IS NULL) A
LEFT JOIN items_categories B
ON A.cat_id=B.subCategory AND B.subCategory IS NOT NULL
GROUP BY 1 ASC
ORDER BY 1 ASC) C;
[/sql]
mysql> SELECT GROUP_CONCAT('<ul>',CONCAT(GLAVNA,'<ul>', CASE ISNULL(SUBCAT) WHEN 1 THEN '' ELSE SUBCAT END,'</ul></li>'),'</ul>') BLA FROM (SELECT CONCAT('<li><a href="#">',A.category,'</a>') GLAVNA, GROUP_CONCAT('<li>',CONCAT('<a href="#">',B.category,'</a>'),'</li>' ORDER BY B.cat_id ASC SEPARATOR '') SUBCAT FROM (SELECT * FROM items_categories WHERE subCategory IS NULL) A LEFT JOIN items_categories B ON A.cat_id=B.subCategory AND B.subCategory IS NOT NULL GROUP BY 1 ASC ORDER BY 1 ASC) C\G
*************************** 1. row ***************************
BLA: <ul><li><a href="#">Главна Категория 1</a><ul><li><a href="#">Подкатегория 2</a></li><li><a href="#">Подкатегория 3</a></li><li><a href="#">Подкатегория 1</a></li></ul></li></ul>,<ul><li><a href="#">Главна Категория 2</a><ul><li><a href="#">Подкатегория 1</a></li><li><a href="#">Подкатегория 2</a></li></ul></li></ul>
1 row in set (0.00 sec)
Резултата се намира в един единствен ред-> $row['BLA'], където всичко е подредено(спрямо главна категория и съответните суб-категории) и таговете са затворени (надявам се) :D

Edit:Ako забелязваш, подкатегория 1 на Главна категория 1 е последна за своята категория , защото в тестовата таблица смених, както показах в предишен пост, чрез update-a стойността на cat_id от 2 на 9, т.е. всичко е ок
 
Окей, наистина сработи, но има само един малък проблем.. ;D След първата главна категория се показва запетая О.О

6076863J.jpg


Огледах уж да не би да има допълнителна сложена запетая някъде, но всичко ми се вижда наред... :?
 
Ами според мен не е от заявката. Пусни я в phpMyAdmin SQL Query Window за всеки случай.
 
А сетих се, защото запетайката е default separator...

[sql]
SELECT GROUP_CONCAT('<ul>',CONCAT(GLAVNA,'<ul>',
CASE
ISNULL(SUBCAT)
WHEN 1
THEN ''
ELSE
SUBCAT
END,'</ul></li>'),'</ul>' SEPARATOR '') BLA FROM
(SELECT
CONCAT('<li><a href="#">',A.category,'</a>') GLAVNA,
GROUP_CONCAT('<li>',CONCAT('<a href="#">',B.category,'</a>'),'</li>' ORDER BY B.cat_id ASC SEPARATOR '') SUBCAT
FROM (SELECT * FROM items_categories WHERE subCategory IS NULL) A
LEFT JOIN items_categories B
ON A.cat_id=B.subCategory AND B.subCategory IS NOT NULL
GROUP BY 1 ASC
ORDER BY 1 ASC) C;
[/sql]Веднъж съм писал SEPARATOR '' , но втория път съм го забравил...
:)
 
Ауу, много ти благодаря! Само че изникна друг проблем.. При съдържанието дадено по-долу на таблицата, се появява странен бъг..
Код:
INSERT INTO `items_categories` (`cat_id`, `category`, `subCategory`) VALUES
(1, 'Мобилни телефони', NULL),
(2, 'Калъфи и протектори', 1),
(3, 'Зарядни устройства', 1),
(4, 'Слушалки', 1),
(5, 'Таблети', NULL),
(6, 'Екранни протектори', 5),
(7, 'Калъфи и протектори', 5),
(8, 'Часовници', NULL),
(9, 'Мъжки', 8),
(10, 'Дамски', 8),
(11, 'Стенни часовници', 8),
(12, 'Компютърна периферия', NULL),
(13, 'Клавиатури', 12),
(14, 'Мишки', 12),
(15, 'Подложки за Мишки', 12),
(16, 'Тонколони и слушалки', 12),
(17, 'Web Камери', 12),
(18, 'Usb Hub', 12),
(19, 'Микрофони', 12),
(20, 'Подаръци', NULL),
(21, 'За Рожден ден', 20),
(22, 'За имен ден', 20),
(23, 'Свети валентин', 20),
(24, 'Годишнина', 20);

Излизат така:
6077063S.jpg


Странното е, че не съм променял нищо по заявката, точно за да не объркам нещо (за първи път се сблъсквам с такава заявка и затова...)

ЕДИТ:
Всъщност се променя резултата при промяна да речем на линковете на главните категории от "#" на "javascript: void(0);" (О.О) :idea:
 
Нещо май CSS-a чупи нещата... Трябва да огледаш page source и евентуално дали има незатворени тагове и т.н. btw ako вместо списъци ползваш <h3> за главни & <p> за суб ще е много по-лесно. Предполагам това е по-скоро дизайнерски проблем, особено ако всички тагове са затворени коректно и са ок.
 

Back
Горе