1

リストタイプのレポートを含むRuby-on-Railsアプリに取り組んでいます。そのテーブル内の 2 つの列は、トランザクション テーブルからの集計です。

では、次の 2 つのテーブルがあるとします。

**items**
id
name
group
price

**transactions**
id
item_id
type
date
qty

これら 2 つのテーブルは、トランザクション テーブルの item_id で接続されています。

ここで、テーブル内の項目テーブル内にいくつかの行のセットを表示し、そのテーブル内に 2 つの計算列を作成したいと考えています。

計算された列 1 (スパークライン データ):

過去 12 か月の type="actuals" のアイテムのトランザクションのスパークライン。データベースからの結果は、カンマで区切られた各月の集計数量を含むテキストである必要があります。例: 15,20,0,12,44,33,6,4,33,23,11,65

計算された列 2 (6 か月の合計販売):

アイテムの合計数量に過去 6 か月の売上を掛けた値。

したがって、結果は次のような列になります。

Item name - Sparkline data - 6m total sale

したがって、結果は何千行にもなる可能性がありますが、おそらくページングされます。

問題は、Rails モデルでこれを行う最も簡単な方法で、パフォーマンスをあまり犠牲にしない方法は何でしょうか? これは ruby​​-on-rails に関する質問ですが、SQL タイプのソリューションがさらに含まれている可能性があります。

4

1 に答える 1

0

コア SQL は次のようになります。

select
        i.id,
        i.name,
        y.sparkline,
        i.price*s.sum totalsale6m
from
        items i left join
        (select
                x.item_id,
                GROUP_CONCAT(x.sumqtd order by datemonth asc SEPARATOR ',') sparkline
        from
                (select
                        t.item_id,
                        date_format(date, '%m') datemonth,
                        sum(qtd) sumqtd
                from
                        transactions t
                where
                        t.type='actuals' and
                        t.date>date_sub(now(), interval 1 year)
                group by
                        t.item_id, datemonth
                ) x
        group by
                x.item_id
        ) y on i.id=y.item_id
        left join 
        (select
                t.item_id,
                sum(qtd) sumqtd
        from
                transactions t
        where
                t.date>date_sub(now(), interval 6 month)
        group by
                t.item_id
        ) s on i.id=s.item_id
group by
        i.id, i.name

いくつかのコメント:

  • 実際のデータがないとテストできませんでした。
  • 売上にギャップがある場合、つまり特定の月に売上がない場合、リストには 12 の要素が含まれません。この場合、x、y テーブルを調整する必要があります
  • 与えられたいくつかの項目の結果のみが必要な場合は、おそらく、項目 ID フィルターをサブクエリの時間の節約により深く配置できます。
于 2013-10-06T14:33:25.230 に答える