PostgreSQL如何按当前星期几过滤schedule表对应字段为true的数据
按当前星期几筛选schedule记录的解决方案
你之前的写法无法生效,是因为你把字段名字符串直接和布尔值true比较了,数据库不会自动将字符串解析为字段名。下面提供几种可行的实现方式:
方法1:使用CASE表达式(最直接的静态SQL)
利用date_part('dow', current_date)返回的星期索引(0=周日,6=周六),通过CASE分支直接匹配对应字段:
SELECT * FROM schedule WHERE CASE date_part('dow', current_date) WHEN 0 THEN sunday WHEN 1 THEN monday WHEN 2 THEN tuesday WHEN 3 THEN wednesday WHEN 4 THEN thursday WHEN 5 THEN friday WHEN 6 THEN saturday END = true;
这种写法简单直观,不需要动态SQL,性能也最优。
方法2:通过JSONB转换实现动态字段匹配
将记录转换为JSONB对象,再用你已经获取到的当前星期字段名作为键取值判断:
SELECT s.* FROM schedule s WHERE to_jsonb(s) ->> ('{sunday,monday,tuesday,wednesday,thursday,friday,saturday}'::text[])[date_part('dow', current_date) + 1] = 'true';
注意这里是和字符串'true'比较,因为->>操作符返回的是文本类型的JSON值。
方法3:动态SQL(适合复杂场景)
如果需要更灵活的动态逻辑,可以用PL/pgSQL生成并执行动态语句:
-- 直接执行动态查询 DO $$ DECLARE current_day_field text := ('{sunday,monday,tuesday,wednesday,thursday,friday,saturday}'::text[])[date_part('dow', current_date) + 1]; BEGIN EXECUTE format('SELECT * FROM schedule WHERE %I = true', current_day_field); END $$; -- 或者创建函数返回结果集 CREATE OR REPLACE FUNCTION get_today_schedules() RETURNS SETOF schedule AS $$ DECLARE current_day_field text := ('{sunday,monday,tuesday,wednesday,thursday,friday,saturday}'::text[])[date_part('dow', current_date) + 1]; BEGIN RETURN QUERY EXECUTE format('SELECT * FROM schedule WHERE %I = true', current_day_field); END $$ LANGUAGE plpgsql; -- 调用函数获取结果 SELECT * FROM get_today_schedules();
format函数里的%I会自动处理标识符转义,避免SQL注入风险。
内容的提问来源于stack exchange,提问作者OmidNN
相关产品推荐
相关产品推荐

