我在PostgreSQL上运行了一个rails 3.2 app,并且我想在我的视图中显示一些数据,这些数据以这种结构存储在数据库中:
+----+--------+------------------+--------------------+
| 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
,这应该是......
Ben 2013-03-01 – Check for debris Toby 2013-03-02 – Carry out Y1.1 2013-03-03 – Check oil seals
我开始采用的方法是运行查询唯一名称并按sched_start_date ASC
排序,然后为每个名称运行查询以获取其任务。
要获取唯一名称列表,SQL将如下所示。
select *
from (
select distinct on (name) name, sched_start_date
from tasks
) p
order by sched_start_date;
我想知道这是否是正确的方法(查询唯一名称然后为其所有任务运行另一个查询),或者是否有更好的rails方式。
答案 0 :(得分:1)
要按照您的描述对数据进行排序,您可能希望在min()
子句中使用ORDER BY
作为window function:
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
(3
)作为最后ORDER BY
项以打破关系,以防每个日期可以有多个。
但输出仍按name
排序,而不是date
。
将所有数据填入一列的特殊格式有点复杂:
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
答案 1 :(得分: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
这不能完全符合您的需求,但应该告诉您从哪里开始。