我正在尝试从SQL导出到.csv,如果我硬编码接受一定数量的参数,它就可以工作。事情是,我想允许用户请求任意数量的参数,并将这些参数传递给where子句。代码应该使这更清楚。
create temporary table bdates as
select tt.date, tt.time, tt.location
from birthdays as bd
inner join days as d
on (d.id = bd.birth_id)
inner join total_time as tt
on (bd.date = tt.date and
bd.time = tt.time and
d.day_of = tt.location)
where tt.date in(:date1, :date2) --defined by user at command line
order by...
\copy bdates to '.csv'
所以我想我想做的是将列表传递给where子句而不是explicit:dates#variables。例如,一个人可以使用参数'2012-01-04 12:00,2012-02-04 12:00,2012-03-04 12:00'运行脚本,或者仅使用两个参数或一个参数。在三个字符串的情况下,字符串将被解析为'2012-01-04 12:00','2012-02-04 12:00','2012-03-04 12:00'。
我已经尝试过string_to_array(),unexst(regexp_matches(:dates,expression))和regexp_split_to_table(:dates,expression),虽然我不知道如何进行连接。我尝试过的各种解决方案产生了许多错误,包括:
无法将text text []强制转换为没有时区的时间戳
无法将类型记录转换为没有时区的时间戳
regexp_split不支持全局选项
WHERE的参数不能返回集合
最后一个特别令人沮丧,我感到茫然,并会感激任何意见。有一种更简单的方法可以做到这一点,不是吗?谢谢!
答案 0 :(得分:2)
试试这个:
create table x(d timestamp);
insert into x values
('jan 2, 2012'),
('february 4, 2012 12:00'),
('jan 4, 2012 12:00'),
('march 1, 2012'),
('may 3, 2012');
查询:
with input as
(
select
'2012-1-2, 2012-01-04 12:00, 2012-02-04 12:00, 2012-03-04 12:00'::text
as d_input
)
,converted_to_array as
(
select ('{' || d_input || '}')::timestamp[] as d_array
from input
)
select d
from x cross join converted_to_array
where d = any(d_array)
输出:
D
January, 02 2012 00:00:00-0800
February, 04 2012 12:00:00-0800
January, 04 2012 12:00:00-0800
实时测试:http://www.sqlfiddle.com/#!1/43d48/26
你也可以使用IN,只需要对行进行不必要的数组:
with input as
(
select
'2012-1-2, 2012-01-04 12:00, 2012-02-04 12:00, 2012-03-04 12:00'::text
as d_input
)
,converted_to_array as
(
select ('{' || d_input || '}')::timestamp[] as d_array
from input
)
select d
from x cross join converted_to_array
where d in (select unnest(d_array))
实时测试:http://www.sqlfiddle.com/#!1/43d48/29
你也可以将它们全部放在一行中:
select d
from x
where d in (select unnest( ('{' || '2012-1-2, 2012-01-04 12:00, 2012-02-04 12:00, 2012-03-04 12:00'::text || '}')::timestamp[] ))
但我犹豫是否这样做,因为它会导致stackoverflow上的水平滚动条: - )
答案 1 :(得分:1)
你几乎拥有最简单,最快捷的方法:
测试表:
CREATE TEMP TABLE t(d date);
INSERT INTO t VALUES
('2012-1-1')
,('2012-1-4')
,('2012-2-2')
,('2012-2-4')
,('2012-3-3')
,('2012-3-4');
在过滤日期而不是时间戳时,您可以简化示例输入:
'2012-01-04 12:00, 2012-02-04 12:00, 2012-03-04 12:00'
为:
'2012-01-04, 2012-02-04, 2012-03-04'
查询(适用于任一输入):
SELECT t.*
FROM t
JOIN (SELECT unnest(string_to_array(
'2012-01-04, 2012-02-04, 2012-03-04', ', ')::date[]) AS d
) x USING (d)
也可以用:
SELECT regexp_split_to_table(
'2012-01-04, 2012-02-04, 2012-03-04', ', ')::date AS d
但regexp_split_to_table()
速度较慢
通常,选择行的JOIN
比相对较慢的IN()
更快。