2014-02-21 8 views
0

у меня есть небольшая проблема у меня есть MySQL таблица называется категориями, который выглядит примерно так:Выбор два полей в UNION ALL и упорядоченность между рядами

| id | parent_id | name | position | status | ... | 
| 1 | 0  | A |  1 | 1 | ... | 
| 2 | 1  | A1 |  2 | 1 | ... | 
| 3 | 2  | A2 |  1 | 1 | ... | 
| 4 | 1  | A3 |  1 | 1 | ... | 
| 5 | 0  | B |  2 | 1 | ... | 

В основном таблица, которая содержит все мои категории с глубиной многоуровневой , каждая категория, являющаяся подкатегорией, имеет parent_id > 0. В любой момент я использую следующий SQL заявление выбрать только верхние уровень категорий, которые имеют parent_id = 0 и их первые ребенок уровня, которые PARENT_ID = идентификатор категории с parent_id = 0.

SELECT * FROM categories WHERE parent_id = 0 UNION ALL SELECT c.* FROM categories c 
INNER JOIN categories p ON c.parent_id = p.id WHERE p.parent_id 

1. Проблемой

Это всегда будет отображаться все категории, даже если у них есть status = 0, что является проблемой. Поэтому я попытался добавить AND status = 1 в оба оператора WHERE, но это не работает, поскольку все категории выбираются независимо от состояния.

Вторая вещь, которую я попробовал это, так как на первом выберите Я только выбор категорий с parent_id = 0, а затем сделать UNION со всеми категориями, где parent_id спичек идентификаторы тех из первого выбора я мог бы просто добавить AND status = 0 только первый SELECT WHERE и то родительская категория, которая имеет статус 0, не будет выбрана, и, таким образом, когда UNION будет создан, ее дети также не будут выбраны. Однако, если я просто добавлю AND status = 1 к первому WHERE, тогда я получаю только категории с parent_id & status = 1, и в UNION ничего не происходит.

2. Проблема
После того, как я это сделать выбор, я бы заказать категории и подкатегории от значения позиции, это может быть сделано в PHP с помощью функции сортировки, но это довольно экспансивной, когда у вас есть какие-то 8000 категории ,

Я пробовал добавить ORDER BY id ASC, position ASC. После моего последнего WHERE заявления я хотел бы его так, что я хотел бы получить выход так:

| id | parent_id | position | 
| 1 | 0  |  1 | 
| 3 | 1  |  1 | 
| 6 | 1  |  2 | 
| 2 | 0  |  2 | 
| 4 | 2  |  1 | 

Или даже:

| id | parent_id | position | 
| 1 | 0  |  1 | 
| 2 | 0  |  2 | 
| 3 | 1  |  1 | 
| 6 | 1  |  2 | 
| 4 | 2  |  1 | 

Я Тота, что второй пример будет довольно тривиально, и я получил его когда мое заявление не включает UNION ALL. Но с UNION мое утверждение точно так же, как со статусом = 1, возвращает только родительские категории.

SELECT * FROM categories WHERE parent_id = 0 UNION ALL SELECT c.* FROM categories c 
INNER JOIN categories p ON c.parent_id = p.id WHERE p.parent_id ORDER BY parent_id ASC, position ASC; 

Поскольку все родители имеют parent_id = 0 они будут перечислены первыми однако отсортированы по позиции, а затем все дети будут заказаны вместе parent_id первым, а затем позиция.

+0

Вы можете создать [в sqlfiddle] (http://sqlfiddle.com/)? – miken32

ответ

1

Если я правильно понял, то я думаю, что вы хотите следующее:

SELECT DISTINCT c.* FROM categories c, categories p 
WHERE c.status<>0 and (c.parent_id = 0 OR (c.parent_id=p.id and p.parent_id=0)) 
ORDER BY c.id,c.position 
+0

Что-то вроде этого, но это выбирает все категории несколько раз. –

+0

Извините, пропущенный отчет. Отредактируйте его снова. – noz