如何在SQL查询的WHERE子句中动态指定字段名匹配当日列?
解决动态匹配星期对应布尔列的查询问题
问题原因
你原来的查询无法运行,是因为"day_"||lower(dayname(now()))会生成一个字符串(比如day_wednesday),SQL会把这个字符串直接和1做比较,而不是把它当作列名去判断该列的值。这种写法不符合SQL的解析逻辑,自然得不到预期结果。
解决方案
方案1:使用CASE表达式(推荐用于关联查询)
这种方式不需要动态SQL,直接通过CASE分支匹配当前星期对应的列,适合嵌入到关联查询中:
select restaurant_id from day_matrix where case lower(dayname(now())) when 'sunday' then day_sunday when 'monday' then day_monday when 'tuesday' then day_tuesday when 'wednesday' then day_wednesday when 'thursday' then day_thursday when 'friday' then day_friday when 'saturday' then day_saturday end = true;
方案2:使用动态SQL(适合需要复用的场景)
如果需要多次调用,可以创建PL/pgSQL函数生成动态查询:
create or replace function get_restaurants_by_current_day() returns table(restaurant_id int) as $$ begin return query execute format( 'select restaurant_id from day_matrix where %I = true', 'day_' || lower(dayname(now())) ); end; $$ language plpgsql; -- 关联其他查询时直接调用函数 select ot.* from other_table ot join get_restaurants_by_current_day() gr on ot.restaurant_id = gr.restaurant_id;
这里用%I代替字符串占位符是为了正确处理列名的标识符转义,避免潜在的语法问题。
方案3:利用PostgreSQL的JSONB特性
将表行转为JSON对象后,动态提取对应键的值进行判断:
select restaurant_id from day_matrix where to_jsonb(day_matrix)->>('day_' || lower(dayname(now()))) = 'true';
内容的提问来源于stack exchange,提问作者Charmi Chavda
相关产品推荐
相关产品推荐

