Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将列表传递给where子句_Sql_Postgresql - Fatal编程技术网

Sql 将列表传递给where子句

Sql 将列表传递给where子句,sql,postgresql,Sql,Postgresql,我正在尝试从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 tota

我正在尝试从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子句,而不是显式的:dates#变量。例如,一个人可以运行带有参数“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()、unnest(regexp_匹配(:dates,expression))和regexp_split_to_table(:dates,expression)),尽管我不确定如何进行联接。我尝试过的各种解决方案产生了许多错误,包括:

无法将类型text[]强制转换为没有时区的时间戳

无法将类型记录强制转换为没有时区的时间戳

regexp_split不支持全局选项

WHERE的参数不能返回集合

最后一个是特别令人沮丧的,我不知所措,并将感谢任何意见。有一个更简单的方法,不是吗?谢谢

试试这个:

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
现场测试:


您还可以在中使用,只是对行不使用数组:

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))
现场测试:


您也可以将它们全部放在一行中:

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上的水平滚动条:-)


现场测试:

您几乎有了最简单、最快的方法:

测试表:

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'
致:

查询(与任一输入一起使用):

也可以通过以下方式完成:

       SELECT regexp_split_to_table(
                       '2012-01-04, 2012-02-04, 2012-03-04', ', ')::date AS d
但是
regexp\u split\u to\u table()
速度较慢。

通常,
JOIN
比()中相对较慢的
更快地选择行。

您不需要正则表达式,只需在字符串周围放一个花括号,然后将其强制转换为
timestamp[]
数组,并且不能在for数组中使用。您必须使用equal和ANY
WHERE expr=ANY(arrayHere)
嘿,谢谢你,这看起来很有希望。明天早上我会仔细看看。太棒了。它起作用了。感谢您提供了多种方法,我使用sql才两天,弄清楚每一种方法是如何工作的会很好。谢谢
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