2013-11-12 2 views
1

У меня есть две таблицы, которые связаны в родитель-ребенок отношенийКак сохранить логические группировки при сортировке в SQL?

Sale 
sale_id | customer_name 

SaleItem 
item_id | sale_id | item_type 

Каждая продажа запись имеет один или несколько соответствующих SaleItem записей. Моя цель - создать список Продажей с их соответствующими SaleItems, показанными как дети. Я могу сделать это с этим запросом:

SELECT s.sale_id, s.customer_name, si.item_id, si.item_type 
FROM Sale s, SaleItem si 
WHERE s.sale_id=si.sale_id 
ORDER BY s.sale_id, si.item_id 

что дает что-то вроде этого (пустые строки будут добавлены для ясности проблемы):

sale_id | customer_name | item_id | item_type 
1  | Sam   | 1  | D 
1  | Sam   | 2  | B 
1  | Sam   | 3  | D 

2  | Nate   | 4  | A 
2  | Nate   | 5  | B 

3  | Mike   | 6  | B 
3  | Mike   | 7  | C 

4  | Nate   | 8  | C 
4  | Nate   | 9  | D 

заказ по статье приведены результаты в логической группировке по продажам с их заказами SaleItems. Это дает мне данные мне нужно, чтобы иметь возможность написать код хорошей складную UI для представления данных:

-Sale 1 - Sam 
-B 
-B 
-D 
+Sale 2 - Nate 
+Sale 3 - Mike 
-Sale 4 - Nate 
-C 
-D 

Это все хорошо и хорошо, но что происходит, когда я хочу, чтобы отсортировать этот список по ITEM_TYPE? Я хочу, чтобы в конечном итоге с результирующего набора, как это (пустые строки будут добавлены для ясности проблемы):

sale_id | customer_name | item_id | item_type 
2  | Nate   | 4  | A 
2  | Nate   | 5  | B 

3  | Mike   | 6  | B 
3  | Mike   | 7  | C 

4  | Nate   | 8  | C 
4  | Nate   | 9  | D 

1  | Sam   | 1  | D 
1  | Sam   | 2  | B 
1  | Sam   | 3  | D 

Пожалуйста, обратите внимание, что каждая продажа и его соответствующие SaleItems остаются вместе. В основном, что мне нужно сделать, это рассматривать каждый набор Sale + SaleItems как один элемент и разумно сортировать их по любому из столбцов. Поскольку мы по существу просто сортируем Sales здесь, а item_type применяется к SaleItem, мы просто сортируем по первому элементу item_type SaleItem и сохраняем исходный отсортированный порядок SaleItems в продаже. Я действительно надеюсь, что это имеет смысл.

У меня есть несколько вопросов:

  1. я буду об этом неправильно? Поскольку каждая запись Sales является «родителем» одной или нескольких записей SalesItem, JOIN кажется излишним, потому что в конечном итоге «родительские» данные дублируются в каждой «дочерней» строке.
  2. Как я могу сортировать эти данные по первому item_type для каждой продажи и по-прежнему держать каждый Sale's SaleItems вместе?

Спасибо тонну.

+0

Возможно, вы хотите изменить предложение Order с ORDER BY item_type – Miller

+0

'ORDER BY sale_id, item_type' – Linger

ответ

0

попробовать что-то вроде этого:

SELECT s.sale_id, 
     s.customer_name, 
     si.item_id, 
     si.item_type, 
     min(si.item_type) OVER (PARTITION BY sale_id) as min_item_type 
FROM Sale s, SaleItem si 
WHERE s.sale_id=si.sale_id 
ORDER BY min_item_type, s.sale_id, si.item_id 

Это даст вам результат, близкий к тому, что вы показали, как пример.

Вы можете заменить min(si.item_type) любой оконной функции (например, max, first, last ...), чтобы получить item_type, что будет «описывать» каждую sale_id группы.

+0

Это отлично работает в PostgreSQL 8.4+, но, к сожалению, я застрял с использованием 8.3. Есть ли у вас какие-либо предложения по достижению одного и того же результата без использования оконных функций? –

+0

@NateThatcher Единственное, что я могу придумать, это «GROUP BY sale_id» в подзапросе и joni этот подзапрос к основному запросу. Не самое эффективное и ясное решение, но оно будет работать. –

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