Sql 在Ruby中过滤数据库表,将代码迁移到Postgres
根据上面的表,我一直在Rails中使用一些基本的东西来构建对它的查询,这些基本的东西工作得非常好。真正的应用程序需要查询其中的10个字段Sql 在Ruby中过滤数据库表,将代码迁移到Postgres,sql,postgresql,where-clause,sql-function,Sql,Postgresql,Where Clause,Sql Function,根据上面的表,我一直在Rails中使用一些基本的东西来构建对它的查询,这些基本的东西工作得非常好。真正的应用程序需要查询其中的10个字段 # Users | id | name | age | | ----- | -------- | ---- | | 1 | Rand | 25 | | 2 | Mat | 24 | | 3 | Perrin | 23 | 我一直想尝试将其移动到数据库中,我在Postgres中提出了这
# Users
| id | name | age |
| ----- | -------- | ---- |
| 1 | Rand | 25 |
| 2 | Mat | 24 |
| 3 | Perrin | 23 |
我一直想尝试将其移动到数据库中,我在Postgres中提出了这个函数
users = User.none
users = users.where(age: params[:age]) if params[:age]
users = users.where(name: params[:name]) if params[:name]
我想知道的是,是否有更好的方法来执行这些多个where
查询,其中每个查询都可以为空,因此不应使用?我想您需要:
CREATE OR REPLACE FUNCTION filter_users(name character varying, age integer)
RETURNS TABLE(
user_id int,
name character varying,
age integer
)
AS $$
select id as user_id, name, age
from users
where (name IS NULL OR name = $1)
and (age IS NULL OR age = $2)
$$ LANGUAGE SQL;
仅当参数不是null
时,每个条件才适用
您可以使用colaesce()
稍微缩短条件(这不会提高查询效率,可能会降低查询速度):
我甚至不知道你的函数是如何编译的 我会这样写:
where 1 = 1
and coalesce(p_name, name) is not distinct from name
and coalesce(p_age, age) is not distinct from age
如果在表中的
name
或age
中允许null
值,则此操作将无效。与没有区别,这将阻止执行者使用索引。@JonathanJacobson:是的,我提到过它不会提高查询效率……这是轻描淡写的。这会降低查询的运行效率。@JonathanJacobson:我可能认为这取决于这些列上是否有索引。。。以及其他因素。我花在回答如此多的问题上的时间教会了我不要做太多的假设。事实上,你可能会这么说。然而,在我看来,你的建议并不算是好的建议。还要注意,您写了“这不一定……”,这暗示在某些情况下,它会使查询更有效。当然,它会编译。他是根据各自的数字引用论点的。坚持这样。它看起来不好看,但没有人说SQL语句应该好看。另外,我看不出有什么理由去测试1是否等于1。
where 1 = 1
and coalesce(p_name, name) is not distinct from name
and coalesce(p_age, age) is not distinct from age
CREATE OR REPLACE FUNCTION filter_users(_name text, _age integer)
RETURNS TABLE(
user_id int,
name text,
age integer
)
AS $$
select id as user_id, name, age
from users
where 1 = 1
and name = coalesce(_name, name)
and age = coalesce(_age, age)
$$ LANGUAGE SQL;