微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Ruby中过滤数据库表,将代码迁移到Postgres

如何解决在Ruby中过滤数据库表,将代码迁移到Postgres

# Users

| id    | name     | age  |
| ----- | -------- | ---- |
| 1     | Rand     | 25   |
| 2     | Mat      | 24   |
| 3     | Perrin   | 23   |

鉴于上面的表格,我一直在Rails中使用基本的东西对它进行查询效果很好。实际的应用程序大约有10个要查询的字段。

users = User.none
users = users.where(age: params[:age])   if params[:age]
users = users.where(name: params[:name]) if params[:name]

我一直想尝试将其移动到数据库中,而我在Postgres中想到了此功能

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;

我想知道的是,是否有更好的方法来执行这些多个where查询,其中每个查询都可以为null,因此不应使用?

解决方法

我想你想要

create or replace function filter_users(
    p_name character varying,p_age integer
)
returns table(
    user_id int,name character varying,age integer
)
as $$
    select id as user_id,name,age
    from users
    where 1 = 1
      and (p_name is null or name = p_name)
      and (p_age  is null or age = p_age)
$$ 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
,

我什至看不到您的函数将如何编译。

这就是我的写法:

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,age
from users
where 1 = 1
  and name = coalesce(_name,name)
  and age  = coalesce(_age,age)

$$ LANGUAGE SQL;

如果您在表中的nullname中允许age值,则此方法将无效。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。