2016-12-05 8 views
1

У меня есть SQLite-базы данных с таблицей с номером документа следующего этой схемой:DBIx :: Class: Как я могу сортировать по нескольким подстрокам столбца?

16-145-45 
16-127-30 
16-141-42 
16-122-14 
15-090-04 
15-089-15 
15-089-05 

Я хотел бы отсортировать ResultSet на первую и последнюю часть числа, как это. Во-первых, все документы, начинающиеся с наивысшего двузначного префикса (16), отсортированы по последним двум цифрам, а затем - с последующим блоком и т. Д.

16-145-45 
16-141-42 
16-127-30 
16-122-14 
15-089-15 
15-089-05 
15-090-04 

Есть ли способ сделать это в DBIx::Class с каким-то пунктом заказ order_by, или что бы подход?

Я попытался следующий, который не работает, потому что средняя часть числа также считается для сортировки:

my @rs = $self->search(undef, 
    { 
     order_by => { -desc => 'me.number' } 
    } 
); 
+1

@Chankey Почему вы удалили sql-тег. Разве это не актуально? – dequid

+1

Я не думаю, что ваш вопрос специфичен для SQL. Это больше о 'DBIx :: Class' и сортировке. –

+0

Вы должны сказать, с каким движком базы данных вы работаете. Если вы не используете PostgreSQL, функция 'split_part' недоступна для вас. Если кто-то не говорит в любом случае, обычное предположение заключается в том, что вы используете MySQL. Обновите свой вопрос и теги. – Borodin

ответ

2

Если вы хотите базу данных для сортировки результатов, вы должны использовать literal SQL ,

Вот пример для Postgres (я добавил пробел после обратной косой черты, чтобы установить подсветку синтаксиса):

my @rs = $self->search(undef, 
    { 
     order_by => \ "split_part(number, '-', 1) || split_part(number, '-', 3) DESC", 
    } 
); 

Или, создавая столбец вывода с +select result set attribute:

my @rs = $self->search(undef, 
    { 
     '+select' => [ 
      { sort_key => \ "split_part(number, '-', 1) || split_part(number, '-', 3)" }, 
     ], 
     '+as' => [ qw(sort_key) ], # Make sort key accessible from DBIC. 
     order_by => { -desc => 'sort_key' }, 
    } 
); 

другой подход состоит в том, чтобы восстановить весь несортированный набор результатов и отсортировать его на стороне клиента. DBIC не имеет каких-либо конкретных функций, которые помогут вам в этом, поэтому просто используйте функцию Perl sort.

+0

Это очень, erm кусковое решение. Почему бы просто не использовать голый «DBI», если вы собираетесь это сделать? В [документации для 'DBIx :: Class :: ResultSet'] (http://search.cpan.org/~ribasushi/DBIx-Class-0.082840/lib/DBIx/Class/ResultSet.pm#order_by) говорится: *" Старый синтаксис scalarref (т.е. order_by => \ 'year DESC') по-прежнему поддерживается, хотя вам настоятельно рекомендуется использовать синтаксис hashref, как описано выше «*. Я также настоятельно рекомендую использовать синтаксис хеш-ссылки. – Borodin

1

Вам нужно извлечь дополнительные столбцы из набора результатов, которые равны значению функции, которую вы хотите отсортировать. Тогда вы можете просто положить эти столбцы в п order_by как обычный

Это предполагает, что ваш номер документа поле называется docnum. Он извлекает все столбцы из Table плюс две подстроки docnum называется docnum1 и docnum3

my $rs = $schema->resultset('Table')->search(undef, 
    { 
     '+select' => [ 
      { substr => [ 'docnum', 1, 2 ], -as => 'docnum1' }, 
      { substr => [ 'docnum', -2 ], -as => 'docnum3' }, 
     ], 
     order_by => [ { -desc => 'docnum1' }, { -desc => 'docnum3' } ], 
    } 
); 
1

Поскольку ответ от @nwellnhof работает как шарм, я просто хотел, чтобы обеспечить соответствующий синтаксис для SQLite, который не знает, функция split_part().

# SQL for filtering the doc number in SQLite 

my @rs = $self->search(undef, 
    { 
     order_by => \ "SUBSTR(me.number, 1, 2) || SUBSTR(me.number, -2, 2) DESC" 
    } 
); 
+0

@ Танкалус: Приносим извинения. Вы абсолютно правы. – Borodin

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

  • Нет связанных вопросов^_^