2011-05-26 14 views
0

我需要做一个这样的查询有没有办法在查询中使用SELECT的结果作为列标识符? (PostgreSQL的)

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    | 

如何正确编写此查询?

回答

2

这一个丑陋的架构......一堆的替代品:

  1. 替换“周一,周二......”由一个整型字段的字段,被解释为一个位掩码 - 或使用bit-string data type

  2. 将它们替换为包含整数(星期几)的单个字段。

  3. 非规范化为一个额外的表,带有一个day_of_week字段和一个FK到日历表。

+0

谢谢我会采纳您的建议并更改架构。 – dan 2011-05-26 14:49:17

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

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

+0

我在上面添加了一些信息。这有帮助吗? – dan 2011-05-26 13:48:29

+0

您有修改数据结构的选择吗?您应该有第二个表格将您的日历时间(开始,结束)与一周中的一天或多天关联起来。然后我认为做出你的查询会更容易。 – Kaltezar 2011-05-26 14:09:48

+0

@dan:非常有启发性。我修改了我的答案,以考虑到新信息。 – 2011-05-26 14:10:40

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

感谢您的精心解答。我认为这是一个好兆头,如果我改变模式,事情会变得更容易。 – dan 2011-05-26 14:49:57

相关问题