2014-02-12 2 views
0

Название - дерьмо, потому что я на самом деле не уверен, что это называется. Я спрашиваю, потому что я не могу быть первым, кто захочет это сделать. (Я использую «все» или WE иметь в виду, не имеет значения)SQL - выбор уникальных, не нулевых вещей и упорядочение - работа с «семьями» вещей

Series table: 
id seriesName 
1 WE 
2 WE 

id title series seriesPosition seriesName 
1 A  0  0    "" 
2 B  1  0    "Part I" 
3 F  1  1    "Part II" 
4 D  1  2    "Part III" 

5 C  2  0    "" 
6 E  2  1    "The return" 
7 G  0  0    "" 

Я хотел бы отсортировать так набор данных в порядке, приведенная выше таблица находится. То есть сказать, что титул сортируется в порядке возрастания, а остальная часть серии следует первой в этой серии. Вот почему 3 и 4 следуют 2, несмотря на 5, предшествующих 3 в алфавитном порядке.

Я предполагаю, что это невозможно сделать в SQL. Поэтому вместо этого я хотел бы выбрать вещи (уникально) с ненулевой серией, но я бы хотел выбрать наименее названный. Затем, когда я обрабатываю результаты, я вижу ненулевой рядId и загружаю данные по мере необходимости.

Я использую SQLite.

Я не думаю, что могу использовать группу, потому что все записи с порядковыми номерами, равными нулю, логически уникальны. Может ли это быть сделано в SQL (или то, что ближе всего я могу получить), или это нужно сделать с моей стороны интерфейса?

Я также говорю о семьях, потому что это то, что представляет собой серия, семейство книг.

+1

Oracle имеет CONNECT BY с предложением ORDER SIBLINGS. но подождите: это просто, что вы хотите заказать по SERIES, а затем SERIES_POSITION? – Randy

+0

@ Рэнди запатентовано? –

+0

Не думайте так - вот документ IBM для того же синтаксиса: http://publib.boulder.ibm.com/infocenter/soliddb/v6r3/index.jsp?topic=/com.ibm.swg.im. soliddb.sql.doc/doc/select.level.and.order.siblings.by.example.html – Randy

ответ

1

Достаточно сказать из приведенных выше комментариев: порядок сортировки здесь запутан!

я концептуализировать его как двухступенчатый процесс:

  • Получить список всех не-серии или первой в серии книг, в алфавитном порядке по названию
  • сращивания в этот список все nth- в серии книг, в порядке серии

Шаг один легко:

SELECT title, series, seriesPosition, seriesName 
FROM books 
WHERE seriesPosition = 0 
ORDER BY title; 

Шаг два г ets сложно. Я решил придумать дополнительный столбец конкатенацией название позиции серии, и назвал этот столбец sortKey:

SELECT title, series, (title || seriesPosition) sortKey 
FROM books 
ORDER BY sortKey; 

Этот обычай SortKey имеет важное значение, но мы не можем просто использовать название каждой книги; мы должны использовать название первой книги в своей серии. Мы можем найти это с помощью автообъединение:

SELECT a.title, a.series, a.seriesPosition, a.seriesName, (b.title || a.seriesPosition) sortKey 
FROM books a 
INNER JOIN books b ON a.series = b.series 
WHERE a.series = 0 OR b.seriesPosition = 0 
ORDER BY sortKey; 

К сожалению, включает в себя повторяющиеся записи для всех книг в серии 0.

Там может быть элегантный способ, чтобы избавиться от них, но так как это 5 вечера Я остановился на союзе между двумя запросами (по одному для каждого в-серии и книги без серии):

SELECT title, series, seriesPosition, seriesName, title sortKey 
FROM books 
WHERE series = 0 
UNION 
SELECT a.title, a.series, a.seriesPosition, a.seriesName, (b.title || a.seriesPosition) sortKey 
FROM books a 
INNER JOIN books b ON a.series = b.series 
WHERE a.series != 0 AND b.seriesPosition = 0 
ORDER BY sortKey; 

You can see a live demo on SQLFiddle.

+0

Извините за позднюю upvote красиво сделано! –

0

ответ Раттер является большим, но действительно это намного проще.Это работает с MySQL:

SELECT *,true as HasSeries, 
    (select SeriesName from Series where Series.SeriesId = Books.SeriesId) as orderName FROM Books WHERE SeriesId != 0 
UNION 
SELECT *,false as HasSeries,Title as orderName FROM Books WHERE SeriesID = 0 
ORDER BY orderName asc, seriesPosition asc; 

Я предположил бы, что он работает с SQLite, если у него есть профсоюзы, это не является идеальным, поскольку это может поставить дополнительную нагрузку на сервер SQL, чем хотелось бы, но да, это один из способов делать это!

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