我正在开发一个用于教育研究的在线应用程序,我经常需要非常复杂的 SQL 查询:
- 查询通常包括 5-20 个连接,通常多次连接到同一个表
- SELECT 字段通常在派生字段/计算和 CASE 语句之间有 30-40 行高
- 根据用户的权限和其他安全设置,在 PHP 中添加了额外的 WHERE 条件
- 用户界面具有搜索和排序控件,可将自定义子句添加到 WHERE / ORDER / HAVING 子句。
目前,这个应用程序是基于 PHP + MYSQL + Jquery 构建的,用于移动部件。(这源于旧的 Dreamweaver 代码。)很快我们将从头开始重建应用程序,目的是整合、清理并为未来的扩展做好准备。虽然我对 PHP 很熟悉,但我正在学习一些关于 Rails 的知识并意识到,也许在更现代的框架上构建 2.0 版本会更好。但在我投入数小时的教程之前,我需要知道 Rails 查询系统(ActiveRecord?)是否能满足我们的查询需求。
这是我关心的一个查询挑战的示例。查询必须从表的 3+“实例”中进行选择,并从每个实例中获取可比较的信息:
SELECT p1.name AS my_name, pm.name AS mother_name, pf.name AS father_name
FROM people p1
JOIN mother pm ON p1.mother_id = pm.id
JOIN father pf ON p1.father_id = pf.id
# etc. etc. etc.
WHERE p1.age BETWEEN 10 AND 16
# (selects this info for 10-200 people)
或者,一个类似的例子,更能代表我们的挑战。一个“原始数据”表多次连接到一个“编码选择”表,每个实例又必须查找与其存储的键关联的文本:
SELECT d.*, c1.coder_name AS name_c1, c2.coder_name AS name_c2, c3.coder_name AS name_c3,
(c1.result + c2.result + c3.result) AS result_combined,
m_c1.selection AS selected_c1, m_c2.selection AS selected_c2. m_c3.selection AS selected_c3
FROM t_data d
LEFT JOIN t_codes c1 ON d.id = c1.data_id AND c1.category = 1
LEFT JOIN t_menu_choice m_c1 ON c1.menu_choice = m_c1.id
LEFT JOIN t_codes c2 ON d.id = c2.data_id AND c2.category = 2
LEFT JOIN t_menu_choice m_c2 ON c2.menu_choice = m_c2.id
LEFT JOIN t_codes c3 ON d.id = c3.data_id AND c3.category = 3
LEFT JOIN t_menu_choice m_c3 ON c3.menu_choice = m_c3.id
WHERE d.date_completed BETWEEN ? AND ?
AND c1.coder_id = ?
这些类型的连接很容易用纯 SQL 编写,当需要搜索过滤器和其他不同的元素时,几个 PHP 循环可以帮助将字符串拼凑成一个完整的查询。但是我还没有看到任何解决这种结构的 Rails / ActiveRecord 示例。如果我需要使用 find_by_sql("") 将每个查询作为纯 SQL 运行,那么与坚持使用我所知道的 PHP 相比,使用 Rails 可能不会有太大的改进。
我的问题是:ActiveRecord 是否支持表需要“昵称”的情况,例如上面的查询?主表也可以有别名吗?(在我的示例中,“p1”或“d”)我对 SELECT 语句中选择的字段有多少控制权?我可以为选定的字段创建别名吗?我可以在 SELECT 子句中进行计算并选择派生字段吗?CASE 语句呢?
如何设置指定连接表别名的 WHERE 条件?我的 WHERE 子句可以包括(使用上面的例子)“ WHERE pm.age BETWEEN p1.age AND 65 ”之类的东西吗?
这种复杂性不仅仅是偶尔出现的奇怪查询,它是应用程序的一个恒定且核心的特性(因为它目前的结构)。我关心的不仅仅是在 Rails 和 ActiveRecord 中编写这些查询是否“可能”;这是“Rails 方式”是否支持这种需求,因为我需要写很多这样的东西。因此,我正在尝试确定切换到 Rails 是否会带来比其价值更多的麻烦。
提前致谢!- 如果您在 Rails 中遇到类似的可怕查询,我很想听听您的故事及其结果。