mysql - 根据可变条件选择多个单个(LIMIT 1)记录

标签 mysql sql ruby-on-rails-3 postgresql database-design

我有两个表,chartschart_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')

最佳答案

这将是 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 子句应按日期选择最新的日期(您也可以为此使用主键,因为它应该是最新的 - 除非您插入自定义日期)。

您可以在 WHERE 子句中使用 BETWEEN 来获取“所有位置”,而无需编写每个可用的位置 1 到 5 英寸之间(或任何您的范围)。

关于mysql - 根据可变条件选择多个单个(LIMIT 1)记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12934611/

相关文章:

mysql - 调整 SSD MySql 性能

php - 在插入或更新之前检查 MySQL 行中的数据

mysql - MySQL 查询中 EXPLAIN、count(1) 和表内容之间的差异

ruby-on-rails - 使用纯 Ruby 代码编写服务器应用程序是否明智?

ruby-on-rails - Rails - 使用 Capistrano 部署后需要重新启动 Nginx?

sql - 从现有 MySQL 数据库创建 ERD 的实用程序?

MySQL 模拟行数

python - 在 python 中模拟类似文件的行为

sql - SQL 存储过程中的动态排序

ruby-on-rails - 如何在 Rails 3 中使用 gem 而不在 Gemfile 中引用它