Schrift
[thread]12999[/thread]

DBIx::Class: ResultSet über eine relativierte Tabelle sorieren

Leser: 1


<< >> 7 Einträge, 1 Seite
pktm
 2009-01-14 17:59
#117987 #117987
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Hallo!

Ich habe 2 Tabellen: T und P, dabei gilt: T.has_many(P) und P hat eine Timestamp-Spalte.
Jetzt will ich, dass Einträge aus A nach der Timestamp-Spalte von P sortiert werden.
Aber ich finde keinen Ansatz dafür.
Wenn ich A und B über JOIN verbinde, erzeuge ich das Kreuzprodukt. Muss ich das noch irgendwie einschränken?

Hier ein Codeschnipsel, das das Kreuzprodult erzeugt:
Code: (dl )
1
2
3
4
5
6
7
	my $rs = $schema->resultset('Thread')->search(
{board_id => $board_id},
{
join => qw/posts/,
order_by => 'posts.timestamp DESC',
}
);


Was mache ich falsch?
http://www.intergastro-service.de (mein erstes CMS :) )
renee
 2009-01-15 10:50
#118012 #118012
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Geh' das über die andere Tabelle an.

Code (perl): (dl )
1
2
3
4
5
6
7
8
    my $rs = $schema->resultset('Posts')->search(
        # threads. durch den Namen der belongs_to-Beziehung P -> T ersetzen
        {'threads.board_id' => $board_id}, 
        {
            prefetch        => qw/threads/, 
            order_by    => 'timestamp DESC',
        }
    );


Edit: Wenn Du die Daten aus der Threads-Tabelle nicht brauchst, kannst Du auch join statt prefetch nehmen
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
pktm
 2009-01-15 17:01
#118025 #118025
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Hm, mal testen. Aber ist das nicht irgendwie um die Ecke egdacht?
Ein Thread hat mehrere Posts, und jeder Post hat einen Timestamp. Es gibt also einen Post, der einen jüngsten Timestamp hat, und der soll zusammen mit den Informationen des Threads zur Verfügung stehen.

Wenn ich das aus der Richtung der Post-Tabelle errechnen kann, dann muss das doch auch in der anderen Richtung gehen?

Aber wie gesagt, testen... :)
http://www.intergastro-service.de (mein erstes CMS :) )
renee
 2009-01-16 13:13
#118079 #118079
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Ok, dann habe ich Dich falsch verstanden. Probier mal:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/perl

use strict;
use warnings;
use Local::DBIC_Schema;

my $schema = Local::DBIC_Schema->connect( 'DBI:SQLite:pktm' );
$schema->storage->debug(1);

my $thread = $schema->resultset( 'T' )->search(
    { 'testid' => 1 },
    { 
        join      => 'Ps',
        '+select' => 'Ps.timestamp',
        '+as'     => 'timestamp',
        order_by  => 'Ps.timestamp DESC',
    }
)->first;

print $thread->get_column( 'timestamp' );
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
pktm
 2009-01-16 13:35
#118081 #118081
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Ja, so in die Richtung sind meine Experimente auch schon gediegen, aber es gibt nicht exakt das aus, was ich suche.

Hier ist mein Ansatz:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
my $rs = $schema->resultset('Thread')->search(undef,
{
join => 'posts',
select => [qw/subject timestamp/],
'+select' => [
{max => 'timestamp'}
],
'+as' => [qw/tmax/],
order_by => 'timestamp DESC',
group_by => 'me.thread_id',
},
);

foreach my $x ( $rs->all() ) {
say $x->get_column('tmax') . " " . $x->subject();
}


Wenn ich die group_by-Klausel weg lasse erhalte ich das Kreuzprodukt aus threads und posts, das will ich nicht. Ich will immer nur eine Liste aller Threads und deren aktuellesten Post.

Das SQL-Statement dazu sieht so aus:
[sql]
SELECT subject, MAX(timestamp) as tmax
FROM threads
LEFT JOIN posts ON posts.thread_id = threads.thread_id
where board_id = 17
group by threads.thread_id
order by tmax DESC
[/sql]

Der Kniff ist, nach MAX(timestamp) sortieren zu können. Wie ich das DBIx::Class mitteile, habe ich noch nicht herausgefunden.

Ich kann zwar die timestamp-Zelle mit selektieren, aber scheinbar kommt dann, trotz Sortierung nach timestamp DESC nicht das richtige Ergebnis.

DBIx::Class produziert bei obigem Code folgendes:
[sql]
SELECT subject, timestamp, MAX( timestamp )
FROM threads me
LEFT JOIN posts posts ON ( posts.thread_id = me.thread_id )
GROUP BY me.thread_id
ORDER BY timestamp DESC
[/sql]

Da wird einfach nach der falschen Zelle sortiert :-s

PS: das $schema->storage->debug(1); ist echt nützlich :)
http://www.intergastro-service.de (mein erstes CMS :) )
renee
 2009-01-16 13:41
#118083 #118083
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Da musst Du wohl mit einem Workaround arbeiten:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
my $rs = $schema->resultset('Thread')->search(undef,
    {
        join => 'posts',
        select => [qw/subject timestamp/],
        '+select' => \'MAX(timestamp) as tmax',
        '+as' => [qw/tmax/],
        order_by => 'tmax DESC',
        group_by => 'me.thread_id',
    },
);

foreach my $x ( $rs->all() ) {
    say $x->get_column('tmax') . " " . $x->subject();
}
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
pktm
 2009-01-16 13:47
#118084 #118084
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Ach, ist ja der Wahnsinn!
Das geht. Witzigerweise hatte ich sogar (beim mehrfachen durchstöbern der Manpage) gelesen, dass man direkt SQL übergeben kann (dank SQL::Abstract), aber auf die Idee, das da anzuwenden, wäre cih jetzt nicht gekommen.

Vielen Dank!
http://www.intergastro-service.de (mein erstes CMS :) )
<< >> 7 Einträge, 1 Seite



View all threads created 2009-01-14 17:59.