AR/Arel - 我如何编写查询 SELECT 列的条件 CONCAT
AR/Arel - How can i compose a query to SELECT a conditional CONCAT of columns
我有一个模型方法,它有条件地连接用户的用户名(“登录”)和真实姓名,如果他们保存了真实姓名 - 否则它只显示用户名。我想在 ActiveRecord 或 Arel 中重写查询。
看来我应该使用 Arel::Nodes::NamedFunction
。但我不明白如何使用命名函数进行 条件 连接。 (Arel 知道“if”吗?我在文档中找不到任何参考。)
def primer_values
connection.select_values(%(
SELECT CONCAT(users.login,
IF(users.name = "", "", CONCAT(" <", users.name, ">")))
FROM users
ORDER BY IF(last_login > CURRENT_TIMESTAMP - INTERVAL 1 MONTH,
last_login, NULL) DESC,
contribution DESC
LIMIT 1000
)).uniq.sort
end
ORDER BY 中也有类似的条件。
虽然通常我讨厌 rails 中的 Raw SQL,但考虑到这种用法,我会保持原样。虽然我可能会把它改成更惯用的东西,比如。
User
.order(
Arel.sql("IF(last_login > CURRENT_TIMESTAMP - INTERVAL 1 MONTH,last_login, NULL)").desc,
User.arel_table[:contribution].desc)
.limit(1000)
.pluck(Arel.sql(
'CONCAT(users.login,
IF(users.name = "", "",
CONCAT(" <", users.name, ">")))'))
.uniq.sort
将其转换为 Arel 而不将其抽象为自己的对象会显着损害可读性。
说这些只是为了给你一个想法;第一部分是 3 NamedFunction
s
- 连接
- 如果
- 连接
Arel::Nodes::NamedFuction.new(
"CONCAT",
[User.arel_table[:name],
Arel::Nodes::NamedFuction.new(
"IF",
[User.arel_table[:name].eq(''),
Arel.sql("''"),
Arel::Nodes::NamedFuction.new(
"CONCAT",
[Arel.sql("' <'"),
User.arel_table[:name],
Arel.sql("'>'")]
)]
)]
)
A NamedFunction
是 FUNCTION_NAME(ARG1,ARG2,ARG3)
的构造函数,因此任何使用此语法的 SQL 都可以使用 NamedFunction
创建,包括空函数,如 NOW()
或其他语法,如 LATERAL(query)
.
我有一个模型方法,它有条件地连接用户的用户名(“登录”)和真实姓名,如果他们保存了真实姓名 - 否则它只显示用户名。我想在 ActiveRecord 或 Arel 中重写查询。
看来我应该使用 Arel::Nodes::NamedFunction
。但我不明白如何使用命名函数进行 条件 连接。 (Arel 知道“if”吗?我在文档中找不到任何参考。)
def primer_values
connection.select_values(%(
SELECT CONCAT(users.login,
IF(users.name = "", "", CONCAT(" <", users.name, ">")))
FROM users
ORDER BY IF(last_login > CURRENT_TIMESTAMP - INTERVAL 1 MONTH,
last_login, NULL) DESC,
contribution DESC
LIMIT 1000
)).uniq.sort
end
ORDER BY 中也有类似的条件。
虽然通常我讨厌 rails 中的 Raw SQL,但考虑到这种用法,我会保持原样。虽然我可能会把它改成更惯用的东西,比如。
User
.order(
Arel.sql("IF(last_login > CURRENT_TIMESTAMP - INTERVAL 1 MONTH,last_login, NULL)").desc,
User.arel_table[:contribution].desc)
.limit(1000)
.pluck(Arel.sql(
'CONCAT(users.login,
IF(users.name = "", "",
CONCAT(" <", users.name, ">")))'))
.uniq.sort
将其转换为 Arel 而不将其抽象为自己的对象会显着损害可读性。
说这些只是为了给你一个想法;第一部分是 3 NamedFunction
s
- 连接
- 如果
- 连接
Arel::Nodes::NamedFuction.new(
"CONCAT",
[User.arel_table[:name],
Arel::Nodes::NamedFuction.new(
"IF",
[User.arel_table[:name].eq(''),
Arel.sql("''"),
Arel::Nodes::NamedFuction.new(
"CONCAT",
[Arel.sql("' <'"),
User.arel_table[:name],
Arel.sql("'>'")]
)]
)]
)
A NamedFunction
是 FUNCTION_NAME(ARG1,ARG2,ARG3)
的构造函数,因此任何使用此语法的 SQL 都可以使用 NamedFunction
创建,包括空函数,如 NOW()
或其他语法,如 LATERAL(query)
.