3

次の列を持つテーブルがあります。id| fk_id | rcv_date

関連するテーブルの外部キーIDを表す共通のfk_idを持つ複数のレコードが存在する場合があります。

各レコードに行番号を割り当て、fk_idでグループ化し、rcv_dateで並べ替えるクエリを作成する必要があります。

私は当初、次のクエリから始めました。これは、行番号の並べ替えと割り当てに非常に適しています。

SELECT @row:=@row +1 AS ordinality, c.fk_id, rcv_date
FROM (SELECT @row:=0) r, mytable c
ORDER BY rcv_date

ただし、行のカウントと並べ替えはデータセット全体で行われます。カウントは共通のfk_id内にある必要があります。たとえば、次のサンプルデータが返されます(最初の列は行数/順序を表します)。

1 | 5 | 2011-10-01
2 | 5 | 2011-10-14
3 | 5 | 2011-11-02
4 | 5 | 2011-12-17
1 | 8 | 2011-09-03
2 | 8 | 2011-11-12
1 | 9 | 2011-10-08
2 | 9 | 2011-10-10
3 | 9 | 2011-11-19

中央の列はfk_idを表します。ご覧のとおり、並べ替えと行数はfk_idの「グループ化」内にあります。

UPDATE 動作しているように見えるクエリがありますが、改善できるかどうかについて入力が必要です。

SELECT IF(@last = c.fk_id, @row:=@row +1, @row:=1) AS ordinality, @last:=c.fk_id, c.fk_id, rcv_date
FROM (SELECT @row:=0) r, (SELECT @last:=0) l, mytable c
ORDER BY c.fk_id, rcv_date

つまり、これはfk_id、次にrcv_dateの順に並べます。これは基本的に私のグループ化を処理します。次に、2番目の変数を使用して、前のレコードのfk_idを現在のレコードと比較します。同じ場合は、行をインクリメントします。異なる場合は、1にリセットします。

実際のデータを使用したテストは機能しているようです。しかし、それはかなり非効率的なクエリだと思います-ですから、誰かがそれを改善するためのアイデアを持っているか、可能性のある欠陥を見つけたら、私は聞いてみたいです。

4

1 に答える 1

3

これはかなり簡単なはずです。

SELECT (CASE WHEN @fk <> fk_id THEN @row:=1 ELSE @row:=@row + 1 END) AS ordinality, 
       @fk:=fk_id, rcv_date
FROM   (SELECT @row:=0) AS r, 
       (SELECT @fk:=0) AS f, 
       (SELECT fk_id, rcv_date FROM files ORDER BY fk_id, rcv_date) AS t

fk_id最初に、すべての外部キーが一緒になるように注文し(実際にテーブルにない場合はどうなりますか?)、次に、優先する注文を行いましたrcv_date。クエリはfk_idの変更をチェックし、変更がある場合は行番号変数が1に設定され、そうでない場合は変数がインクリメントされます。そのincaseステートメントで処理されます。@fk:=fk_idケースチェックの後に行われることに注意してください。そうでない場合は、行番号に影響します。

編集:たまたま私が最終的に得たものと同じであるあなた自身の解決策に気づきました。称賛!:)

于 2012-11-04T06:58:42.863 に答える