【问题标题】:Is it possible to implement SUBSTRING_INDEX logic using Ruby Sequel to create a column alias?是否可以使用 Ruby Sequel 实现 SUBSTRING_INDEX 逻辑来创建列别名?
【发布时间】:2015-11-14 00:34:21
【问题描述】:

我有一个客户,他有一个图像/媒体数据库,该数据库使用文件命名约定,该约定包含文件名中每个图像的页码。

图像是书籍的扫描件,第 1 页通常只是封面图像,书籍的实际“第 1 页”是在类似于第 3 次扫描的地方扫描的。考虑到这一点,数据库中的文件名看起来像这样字段filename:

  • great_book_001.jpg
  • great_book_002.jpg
  • great_book_003_0001.jpg
  • great_book_004_0002.jpg
  • great_book_005_0003.jpg

考虑到这一点,我想使用 MySQL 的 SUBSTRING_INDEX 从文件名中提取页码。使用纯 MySQL 时,我花了大约 5 分钟才想出这个效果很好的原始查询:

SELECT `id`, `filename`, SUBSTRING_INDEX(SUBSTRING_INDEX(`filename`, '.',  1), '_',  -1) as `page`
FROM  `media_files`
WHERE CHAR_LENGTH(SUBSTRING_INDEX(SUBSTRING_INDEX(`filename`, '.',  1), '_',  -1)) = 4
ORDER BY `page` ASC
;

问题是我想了解是否可以在使用Sequel Gem for Ruby 的同时使用SUBSTRING_INDEX 实现列别名?

到目前为止,我似乎无法通过像这样初始创建数据集来做到这一点:

# Fetch a dataset of media files.
one_to_many :media_files, :class => MediaFiles,
  :key => :id, :order => :rank

由于返回的数据集是一个数组,我正在使用Ruby map method 滚动获取的数据集,然后在使用the Ruby mergepage 插入数据集之前进行一些字符串处理:

# Roll through the dataset & set a page value for files that match the page pattern.
def media_files_final
  media_files.map{ |m|
    split_value = m[:filename].split(/_/, -1).last.split(/ *\. */, 2).first
    if split_value != nil && split_value.length == 4
      m.values.merge({ :page => split_value })
    else
      m.values.merge({ :page => nil })
    end
  }
end

效果很好。但是,与一个可以一举完成的简单 MySQL 查询相比,这对我来说似乎很笨拙。所以问题是,有什么方法可以使用Sequel Gem for Ruby 达到相同的结果?

我猜想SUBSTRING_INDEX 在 Sequel 框架中可能不容易得到支持。但如果没有,我是否有机会插入原始 MySQL 而不是使用 Sequel 方法来实现这个目标?

【问题讨论】:

  • 你试过执行任意 SQL 代码吗?: result = DB.run("SELECT id, filename, SUBSTRING_INDEX(SUBSTRING_INDEX(filename, '.', 1), '', -1) as page FROM media_files WHERE CHAR_LENGTH(SUBSTRING_INDEX(SUBSTRING_INDEX(filename, '.', 1), '', -1)) = 4 ORDER BY @987654346 @ ASC ;") 或者这不是你要找的?
  • 这是一个可能的答案,但看看我的代码在one_to_many Sequel 类模型的上下文中如何工作?
  • 你的意思是:book.media_files ?
  • 我不确定,但你可以试试: one_to_many :media_files, :class=> MediaFiles, :key => :id, :order => :page do { |ds| ds.select{[:id, : 文件名, 'SUBSTRING_INDEX(SUBSTRING_INDEX(filename, '.', 1), '', -1) as page']}.where("CHAR_LENGTH(SUBSTRING_INDEX(SUBSTRING_INDEX) (filename, '.', 1), '', -1)) = ?", 4) }.
  • 感谢@Surya 的努力,但这些想法似乎都不起作用。

标签: mysql ruby substring sequel


【解决方案1】:

如果您希望您的关联使用额外的选定列和过滤器,只需使用 :select:conditions 选项:

substring_index = Sequel.expr{SUBSTRING_INDEX(SUBSTRING_INDEX(:filename, '.',  1), '_',  -1)}
one_to_many :media_files, :class => MediaFiles,
  :key => :id, :order => :page,
  :select=>[:id, :filename, substring_index.as(:page)],
  :conditions => {Sequel.function(:CHAR_LENGTH, substring_index) => 4}

【讨论】:

  • 谢谢杰里米!很棒的信息。
猜你喜欢
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
  • 2018-09-27
  • 2013-02-01
  • 1970-01-01
  • 2016-06-22
相关资源
最近更新 更多