我有两个表格charts
和chart_entries
,我希望获得当前前5个图表位置(基于在给定位置选择最新的chart_entries
)。
有没有办法让这个单一的查询?理想情况下,我的图表将有多达500个位置,因此这样的多个查询实际上是不可行的。
在rails中,我目前正在Chart.rb
def table
(1..5).each do |i|
chart_entries.where(position: i).order('entered_at DESC').first
end
end
生成以下SQL
SELECT "chart_entries".* FROM "chart_entries" WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" = 1 ORDER BY entered_at DESC LIMIT 1
SELECT "chart_entries".* FROM "chart_entries" WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" = 2 ORDER BY entered_at DESC LIMIT 1
SELECT "chart_entries".* FROM "chart_entries" WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" = 3 ORDER BY entered_at DESC LIMIT 1
SELECT "chart_entries".* FROM "chart_entries" WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" = 4 ORDER BY entered_at DESC LIMIT 1
SELECT "chart_entries".* FROM "chart_entries" WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" = 5 ORDER BY entered_at DESC LIMIT 1
这是表结构(postgresql)
CREATE TABLE chart_entries (
id integer NOT NULL,
chart_id integer,
entity_id integer,
"position" integer,
entered_at timestamp without time zone,
locale character varying(255)
);
CREATE TABLE charts (
id integer NOT NULL,
name character varying(255)
);
这是我的最终解决方案
chart_entries.where(position: [1..5]).group('position, id').having('entered_at = MAX(entered_at)').order('position ASC')
答案 0 :(得分:2)
这对GROUP BY
来说是个很好的选择:
SELECT
*
FROM
chart_entries
WHERE
chart_id = 1
AND position BETWEEN 1 AND 5
GROUP BY
position
HAVING
entered_at = MAX(entered_at)
使用GROUP BY
将为每个位置选择一行。 HAVING
子句应该按日期选择最新的子句(您也可以使用主键,因为应该是最新的 - 除非您插入自定义日期)。
您可以在position
子句中使用BETWEEN
来获取 1和5之间的所有位置,而不是需要编写每个WHERE
个可用内容。 (或者你的范围是什么)。
答案 1 :(得分:1)
使用MAX
& GROUP BY
SELECT MAX("chart_entries".id) FROM "chart_entries"
WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" IN (1,2,3,4,5)
ORDER BY entered_at DESC
GROUP BY "chart_entries"."position"