2013-10-02 4 views
1

ОК, отчасти трудно найти этот вопрос в качестве правильного названия, поскольку я не уверен, что бы вы назвали этой функцией.MySQL, как дать строке определенное число

Итак, у меня есть таблица под названием категории, она содержит ID, ParentID, Name, OrderNo плюс еще несколько.

Что я хочу сделать, это дать каждой категории OrderNo, по номеру заказа я имею в виду, если моя категория дерево выглядит следующим образом:

Computers 
Computers > Laptops 
Computers > Desktops 
Computers > Components > Hard Drives 
Computers > Components > Monitors 
TVs 
TVs > LED 
TVs > LCD 

Так я просто хочу, чтобы дать каждой категории значение для OrderNo, которая начинается от 1. Так

Computers 1 
Computers > Laptops 1 
Computers > Desktops 2 
Computers > Components 3 
Computers > Components > Hard Drives 1 
Computers > Components > Monitors 2 
TVs 2 
TVs > LED 1 
TVs > LCD 2 

Надеемся, что это имеет смысл, что он пытается объяснить, что я пытаюсь сделать. К сожалению, я понятия не имею, как будет вызвана такая функция, иначе я бы это сделал.

Мой первоначальный оператор выбора будет выглядеть примерно так:

select ID,ParentID,Name,OrderNo 
from categories 
Order by ParentID,ID 

но не знаю, как продвигать его дальше. К сожалению для мусора объяснения Заранее спасибо Джон

+1

Может быть, вы можете найти что-то полезное здесь: Http: // mikehillyer .com/articles/manage-hierarchical-data-in-mysql/ – Barmar

+0

Значит, вам нужен индекс уровня в иерархических данных? – Orbling

+0

@ Испуганно, да, наверное. – user2231688

ответ

1

Если вы хотите создать его на лету в SELECT, вы можете использовать следующий запрос. Он может использоваться как вход в запрос UPDATE для установки значений. Сделать его одной строкой версии Wrikken's answer.

SQLFiddle: http://sqlfiddle.com/#!2/c41b5/8(завернутые версия: http://sqlfiddle.com/#!2/c41b5/13)

SELECT c.`ID`, 
     c.`ParentID`, 
     c.`Name`, 
     @running := IF(@prevParentID <=> c.`ParentID`, @running + 1, 1) AS `OrderNoCalc`, 
     @prevParentID := c.`ParentID` AS `prevParentID` 
FROM `Categories` c, 
    (SELECT @running := 0) r, 
    (SELECT @prevParentID := NULL) p 
ORDER BY c.`ParentID`, c.`Name` 

Если предположить, что схема выглядит так:

CREATE TABLE `Categories` (
    `ID` int(10) NOT NULL auto_increment, 
    `ParentID` int(10) default NULL, 
    `Name` varchar(32) NOT NULL default '', 
    `OrderNo` int(10) default NULL, 
    PRIMARY KEY (`ID`), 
    KEY `ParentID` (`ParentID`), 
    KEY `OrderNo` (`ParentID`, `OrderNo`) 
) ENGINE=InnoDB AUTO_INCREMENT=1; 

INSERT INTO `Categories` VALUES (1, NULL, 'Computers', NULL); 
INSERT INTO `Categories` VALUES (2, NULL, 'TVs', NULL); 
INSERT INTO `Categories` VALUES (3, 1, 'Laptops', NULL); 
INSERT INTO `Categories` VALUES (4, 1, 'Desktops', NULL); 
INSERT INTO `Categories` VALUES (5, 1, 'Components', NULL); 
INSERT INTO `Categories` VALUES (6, 5, 'Hard Drives', NULL); 
INSERT INTO `Categories` VALUES (7, 5, 'Monitors', NULL); 
INSERT INTO `Categories` VALUES (8, 2, 'LCD', NULL); 
INSERT INTO `Categories` VALUES (9, 2, 'LED', NULL); 
+0

спасибо. Дайте ему попробовать, и, похоже, это трюк. Да, он будет частью сценария экспорта, поэтому нет необходимости его устанавливать в базу данных или что-то еще. Тем не менее, он будет усложняться, поскольку я выбираю около 15 столбцов, из которых несколько уже присоединяются, так как бы я работал в этом уравнении, и мне нужно включить @prevParentID: = c.'ParentID' AS ' prevParentID' как его не значение, которое я хочу включить в мой экспорт – user2231688

+1

Да, проблема в том, что я не могу использовать 'JOIN (SELECT @var)' трюк в 'UPDATE', по-видимому;). Вы можете [заимствовать NULL-безопасное сравнение, хотя] (http://sqlfiddle.com/#!2/c41b5/8): '@prevParentID = c.ParentID OR (@prevParentID IS NULL И c.ParentID IS NULL) '=>' @prevParentID <=> c.ParentID' as ('NULL <=> NULL' является' истинным') – Wrikken

+0

@ user2231688: Это неотъемлемая часть запроса, так как присутствие в 'SELECT' назначение должно куда-то идти. Вы можете обернуть его во внешнем SELECT, чтобы извлечь только те значения, которые вы хотели, возможно, назначение могло быть зарыто в некотором значении функции, которое было проигнорировано. – Orbling

2
SET @parent=0; 
SET @sort=1; 
UPDATE categories 
SET OrderNo = (@sort := IF(
     ParentID <=> @parentid, 
     @sort+1, 
     1 + IF(@parentid := ParentID,0,0) 
)) 
ORDER BY parentid; 

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

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