有没有办法在查询中使用SELECT的结果作为列标识符? (PostgreSQL的)

问题描述 投票:0回答:3

我需要做这样的查询

select * from calendar where (select to_char(now(), 'day')) = true;

但这是无效的,并与ERROR: failed to find conversion function from unknown to boolean失败。

我正在尝试写的查询,今天运行时可以归结为

select * from calendar where thursday = true;

但明天应该是

select * from calendar where friday = true;

该表具有此架构

mbta=# \d calendar
             Table "public.calendar"
   Column   |          Type          | Modifiers 
------------+------------------------+-----------
 service_id | character varying(255) | not null
 monday     | boolean                | 
 tuesday    | boolean                | 
 wednesday  | boolean                | 
 thursday   | boolean                | 
 friday     | boolean                | 
 saturday   | boolean                | 
 sunday     | boolean                | 
 start_date | integer                | 
 end_date   | integer                | 

如何正确编写此查询?

postgresql
3个回答
2
投票

这是一个丑陋的架构......一堆替代方案:

  1. 用单个整数字段替换'monday,tuesday ...'字段,将其解释为位掩码 - 或者使用bit-string data type
  2. 将它们替换为包含整数数组(星期几)的单个字段。
  3. 非规范化为一个额外的表,其中包含一个day_of_week字段和一个FK到您的日历表。

2
投票

是的,有一个解决方案。显然,您不能使用子选择的结果代替列,但您可以重新排列关系以适合该类查询。首先,构建一个子列表,将单个列转换为单个列

SELECT calendar.*, 'monday' AS weekday, monday AS dayvalue FROM calendar
UNION ALL
SELECT calendar.*, 'tuesday' AS weekday, tuesday AS dayvalue FROM calendar
UNION ALL
SELECT calendar.*, 'wednesday' AS weekday, wednesday AS dayvalue FROM calendar
UNION ALL
SELECT calendar.*, 'thursday' AS weekday, thursday AS dayvalue FROM calendar
UNION ALL
SELECT calendar.*, 'friday' AS weekday, friday AS dayvalue FROM calendar
UNION ALL
SELECT calendar.*, 'saturday' AS weekday, saturday AS dayvalue FROM calendar
UNION ALL
SELECT calendar.*, 'sunday' AS weekday, sunday AS dayvalue FROM calendar

然后你可以把它作为一个子选择包装起来,并选择正确的工作日行:

SELECT * FROM (
    SELECT calendar.*, 'monday' AS weekday, monday AS dayvalue FROM calendar
    UNION ALL
    SELECT calendar.*, 'tuesday' AS weekday, tuesday AS dayvalue FROM calendar
    UNION ALL
    ...         -- You get the idea.
    UNION ALL
    SELECT calendar.*, 'sunday' AS weekday, sunday AS dayvalue FROM calendar
) AS ss WHERE to_char(now(), 'day') = ss.weekday AND dayvalue = true; 

0
投票
select * from calendar where (to_char(now(), 'day') != 'Monday' || monday) && (to_char(now(), 'day') != 'Tuesday' || tuesday) && …

鉴于新的架构,我认为这样的事情是你最好的选择。

© www.soinside.com 2019 - 2024. All rights reserved.