1

Rails 3.2 アプリを PostgreSQL で実行しており、ビューに表示したいデータがいくつかあります。これらのデータは、次の構造でデータベースに保存されています。

+----+--------+------------------+--------------------+
| id | name   | sched_start_date | task               |
+----+--------+------------------+--------------------+
| 1  | "Ben"  | 2013-03-01       | "Check for debris" |
+----+--------+------------------+--------------------+
| 2  | "Toby" | 2013-03-02       | "Carry out Y1.1"   |
+----+--------+------------------+--------------------+
| 3  | "Toby" | 2013-03-03       | "Check oil seals"  |
+----+--------+------------------+--------------------+

名前ごとにタスクのリストを表示し、名前がASC最初のものから順に並べられるようにしsched_start_dateたいと思います。これは次のようになります...

ベン
2013-03-01 – 破片のチェック

トビー
2013-03-02 – Y1.1 の実施
2013-03-03 – オイルシールのチェック

私が取り始めたアプローチは、一意の名前のクエリをsched_start_date ASC実行し、それらを .

一意の名前のリストを取得するには、SQL は次のようになります。

select * 
from (
   select distinct on (name) name, sched_start_date 
   from tasks
) p 
order by sched_start_date;

これが正しいアプローチ (一意の名前をクエリしてから、すべてのタスクに対して別のクエリを実行する) であるかどうか、またはレールのより良い方法があるかどうかを知りたいです。

4

2 に答える 2

1

説明したようにデータを並べ替えるには、句でウィンドウ関数min()として使用することをお勧めします。ORDER BY

SELECT name, sched_start_date, task
FROM   tasks
ORDER  BY min(sched_start_date) OVER (PARTITION BY name), 1, 2, 3

ORDER BY名前ごとに最も早い日付を取得するには、元のクエリに追加の項目が必要になります。

SELECT DISTINCT ON (name) name, sched_start_date, task
FROM   tasks
ORDER  BY 1, 2, 3;

また、日付ごとに複数の可能性がある場合に備えて、同点を破るために最後の項目としてtask( ) を追加しました。3ORDER BY

ただし、出力はnameではなく で順序付けられdateます。

すべてのデータを 1 つの列に詰め込んだ独自の形式を取得するのは、もう少し複雑です。

SELECT one_col
FROM  (
    WITH x AS (
        SELECT name, min(sched_start_date) AS min_start
        FROM   tasks
        GROUP  BY 1
        )
    SELECT 2 AS rnk, name
          ,sched_start_date::text || ' – ' || task AS one_col
          ,sched_start_date, min_start
    FROM   tasks
    JOIN   x USING (name)

    UNION ALL
    SELECT 1 AS rnk, name, name, NULL::date, min_start
    FROM   x

    ORDER  BY min_start, name, rnk, sched_start_date, task
    ) y
于 2013-04-01T15:20:02.287 に答える
0

モデルに関連付けがあると仮定すると、実行できる

@employees = Employee.order(:name, :sched_start_date, :task).includes(:tasks)

次に、それらを反復処理できます。

@employees.each do |employee|
  employee.name
  employee.tasks.each do |task|
    task.name
  end
end

これはあなたのニーズに完全に一致するわけではありませんが、どこから始めるべきかを示すはずです。

于 2013-04-01T13:54:45.273 に答える