2016-12-05 3 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を並べ替えしたいと思います。まず、最後の2桁でソートされた上位2桁の接頭辞(16)で始まり、次のブロックと同じようにすべての文書が続きます。

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

カスタムorder_by句のいくつかの並べ替えとDBIx::Classでこれを行う方法はありますか、どのようなアプローチでしょうか?

数の中間部分もソートするために考えられているので、私は、動作しない、次のことを試してみました:

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

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' }, 
    } 
); 

別:+select result set attributeと出力列を作成することにより、

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

または:ここ

はPostgresのための例です(私は、構文の強調表示を修正するために、バックスラッシュの後にスペースを追加しました)アプローチは、ソートされていない結果セット全体を取得し、それをクライアント側でソートすることです。 DBICには特別な機能がありませんので、Perlの sort関数を使用してください。

+0

これは非常に塊のような解決策です。なぜあなたはそれをやろうとしたら、裸の 'DBI'を使用しないのですか? [DBIx :: Class :: ResultSet'(http://search.cpan.org/~ribasushi/DBIx-Class-0.082840/lib/DBIx/Class/ResultSet.pm#order_by)のドキュメントには、上記の「*」で概説したhashref構文を使用することを強くお勧めしますが、古いスカラーの構文(つまりorder_by => \ 'year DESC')も引き続きサポートされています。また、ハッシュリファレンス構文を使用することを強くお勧めします。 – Borodin

1

ソートする関数の値と等しい列を結果セットから抽出する必要があります。次に、あなただけの通常の

としてorder_by句でそれらの列を置くことができるこれはあなたの文書番号フィールドがdocnumと呼ばれていることを前提としています。それはTableからすべての列をフェッチプラスdocnumの2つのサブストリングがdocnum1

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からの答えは魔法のように動作するのでdocnum3と呼ばれ、私は知らない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

@Tanktalus:私の謝罪。あなたは絶対に正しいです。 – Borodin

関連する問題