2010-12-15 4 views
0

ich eine einfache zeitliche Tabelle haben, die wie folgt aussieht:Wie bestellen vor GROUP mit DBIx :: Class

Table: item_approval 

item user status   modified 
2  fred approved  2010-12-01 00:00:00 
3  fred approved  2010-12-02 00:00:00 
4  fred disapproved 2010-12-03 00:00:00 
7  jack unapproved  2010-12-05 00:00:00 
4  fred approved  2010-12-06 00:00:00 
4  jack unapproved  2010-12-07 00:00:00 
4  fred disapproved 2010-12-04 00:00:00 

Ich verwende DBIx :: Class. Mein "Item" Ergebnis wird definiert mit:

__PACKAGE__->has_many(
    "item_approvals", 
    "Schema::Result::ItemApproval", 
    { "foreign.item" => "self.id" }, 
    { cascade_copy => 0, cascade_delete => 0 }, 
); 

Was bedeutet, was ich tun kann:

my $item = $schema->resultset('Item')->find({id=>4}); 

was in Ordnung ist. Dann kann ich tun:

my @approvals = $item->item_approvals; 

zu bekommen resultset wie folgt aus:

item user status   modified 
4  fred disapproved 2010-12-03 00:00:00 
4  fred approved  2010-12-06 00:00:00 
4  jack unapproved  2010-12-07 00:00:00 
4  fred disapproved 2010-12-04 00:00:00 

Meine Frage: Wie kann ich den Satz von Fred und Jacks einzige letzten Genehmigungsstatus? Das heißt, ich möchte diese resultset bekommen:

item user status   modified 
4  fred approved  2010-12-06 00:00:00 
4  jack unapproved  2010-12-07 00:00:00 

ich Dinge wie diese versucht:

my @approvals = $item->search({}, { 
    group_by => 'user', 
    order_by => {-desc => 'modified'} 
}); 

aber die "ORDER BY" wird nach die "GROUP BY" ausgeführt, so dass ich Dinge wie diese stattdessen:

item user status   modified 
4  fred disapproved 2010-12-03 00:00:00 
4  jack unapproved  2010-12-07 00:00:00 

Hilfe?

+0

Ich weiß nicht perl oder dbix, aber die SQL-Art, dies zu tun wäre, Ihr 'modifiziertes' Feld ein' MAX (geändert) als 'Modified' zu machen, das das höchste Datum pro Benutzer zurückgeben würde. – JNK

+0

Ich habe mit diesem ein bisschen gespielt, mit Dingen wie: SELECT Element, Benutzer, Status, MAX (modifiziert) als Most_recent FROM item_approval WHERE id = 4; aber es gibt nicht das höchste Datum zurück * pro Benutzer *; es gibt nur die einzelne Zeile mit dem höchsten Datum zurück. –

+0

müssen Sie sowohl 'MAX (Modified)' als auch 'GROUP BY User' eingeben. Das 'MAX' ohne' GROUP' gibt Ihnen das Maximum für die Abfrage. Die 'GROUP BY' gibt Ihnen das Maximum (oder andere Aggregatfunktionen wie' SUM', 'AVG', etc) für jede Gruppe in der' GROUP BY'. – JNK

Antwort

1

Von dem Verhalten in Ihren Kommentaren beschrieben Ich bin davon ausgegangen, Ihre Datenbank ist MySQL. Ich nehme auch an, dass Ihre item_approval Tabelle einen Primärschlüssel hat, den ich PK nennen werde.

Eine Option ist eine Unter verwenden wählen Sie die Zeile auswählen, die die größte (jüngste) modified Wert hat:

select item, user, status, modified 
from item_approval me 
where PK = (select s.PK from item_approval s where me.item = s.item and me.user = s.user order by s.modified desc, s.PK desc limit 1) 
and me.item = 4 

Dies ist eine ziemlich langsame Option, da sie die Unter wählen für erneut ausgeführt werden jede Zeile und dann alle außer einer Zeile für jede Element/Benutzer-Kombination ablehnen. Andere Datenbanken haben etwas andere Möglichkeiten, um ähnliche Ergebnisse zu erzielen.

Verwandte Themen