从查询批量插入 table (postgresql)
bulk insert from a query into table (postgresql)
我找不到这个问题的答案:
我想将此查询的结果插入 table 'days':
WITH days AS (
SELECT
date_part('dow',generate_series('2017-11-01','2017-11-30', interval '1 day')) as dow,
to_char(generate_series('2017-11-01','2017-11-30', interval '1 day'),'YYYY-MM-DD') as date )
SELECT 0 as id,date,
CASE
WHEN dow=1 then 8
WHEN dow=2 then 8
WHEN dow=3 then 8
WHEN dow=4 then 8
WHEN dow=5 then 8
WHEN dow=6 then 0
WHEN dow=0 then 0
ELSE 0 END as wtime
FROM days
table就这么简单:
CREATE TABLE days
(id serial, dates date, wtime numeric(8,2));
在我的梦想中它应该是这样的:
INSERT * INTO days FROM (
WITH days AS (
SELECT
date_part('dow',generate_series('2017-11-01','2017-11-30', interval '1 day')) as dow,
to_char(generate_series('2017-11-01','2017-11-30', interval '1 day'),'YYYY-MM-DD') as date )
SELECT 0 as id,date,
CASE
WHEN dow=1 then 8
WHEN dow=2 then 8
WHEN dow=3 then 8
WHEN dow=4 then 8
WHEN dow=5 then 8
WHEN dow=6 then 0
WHEN dow=0 then 0
ELSE 0 END as wtime
FROM days)
这可能吗?怎么样?
CTE (WITH
) 需要先出现,然后是插入。您还需要为 CTE 指定一个不同的名称,否则名称 days
会产生歧义
with gen_days (
...)
insert into days
select *
from gen_days;
但是您会遇到问题,因为您的查询会为 date
列生成 varchar 值,而不是真正的 DATE
类型。您需要更改它以将 generate_series()
的结果转换为日期。您也只需要一个 generate_series()
而不是两个:
WITH gen_dates AS (
SELECT date_part('dow',d.dt) as dow,
dt::date as date
from generate_series('2017-11-01','2017-11-30', interval '1 day') as d(dt)
)
insert into days (dates, wtime)
SELECT date,
CASE
WHEN dow=1 then 8
WHEN dow=2 then 8
WHEN dow=3 then 8
WHEN dow=4 then 8
WHEN dow=5 then 8
WHEN dow=6 then 0
WHEN dow=0 then 0
ELSE 0
END as wtime
FROM gen_dates
无关,但是:您并不真的需要 CTE。您可以将插入简化为:
insert into days (dates, wtime)
SELECT dt::date,
CASE date_part('dow', dt)
WHEN 1 then 8
WHEN 2 then 8
WHEN 3 then 8
WHEN 4 then 8
WHEN 5 then 8
WHEN 6 then 0
WHEN 0 then 0
ELSE 0
END as wtime
FROM generate_series('2017-11-01','2017-11-30', interval '1 day') as d(dt);
请注意 CASE
语句的简短形式,您不必重复测试所针对的表达式。
也许您的问题是 CTE 和您的目标 table 同名。
另一个问题是您的 "date" 源列不是真正的 date
数据类型:
INSERT * INTO days
WITH days_cte AS (
SELECT
date_part('dow',generate_series('2017-11-01','2017-11-30', interval '1 day')) as dow,
to_char(generate_series('2017-11-01','2017-11-30', interval '1 day'),'YYYY-MM-DD') as date )
SELECT 0 as id, "date"::date,
CASE
WHEN dow=1 then 8
WHEN dow=2 then 8
WHEN dow=3 then 8
WHEN dow=4 then 8
WHEN dow=5 then 8
WHEN dow=6 then 0
WHEN dow=0 then 0
ELSE 0 END as wtime
FROM days_cte
我找不到这个问题的答案:
我想将此查询的结果插入 table 'days':
WITH days AS (
SELECT
date_part('dow',generate_series('2017-11-01','2017-11-30', interval '1 day')) as dow,
to_char(generate_series('2017-11-01','2017-11-30', interval '1 day'),'YYYY-MM-DD') as date )
SELECT 0 as id,date,
CASE
WHEN dow=1 then 8
WHEN dow=2 then 8
WHEN dow=3 then 8
WHEN dow=4 then 8
WHEN dow=5 then 8
WHEN dow=6 then 0
WHEN dow=0 then 0
ELSE 0 END as wtime
FROM days
table就这么简单:
CREATE TABLE days
(id serial, dates date, wtime numeric(8,2));
在我的梦想中它应该是这样的:
INSERT * INTO days FROM (
WITH days AS (
SELECT
date_part('dow',generate_series('2017-11-01','2017-11-30', interval '1 day')) as dow,
to_char(generate_series('2017-11-01','2017-11-30', interval '1 day'),'YYYY-MM-DD') as date )
SELECT 0 as id,date,
CASE
WHEN dow=1 then 8
WHEN dow=2 then 8
WHEN dow=3 then 8
WHEN dow=4 then 8
WHEN dow=5 then 8
WHEN dow=6 then 0
WHEN dow=0 then 0
ELSE 0 END as wtime
FROM days)
这可能吗?怎么样?
CTE (WITH
) 需要先出现,然后是插入。您还需要为 CTE 指定一个不同的名称,否则名称 days
会产生歧义
with gen_days (
...)
insert into days
select *
from gen_days;
但是您会遇到问题,因为您的查询会为 date
列生成 varchar 值,而不是真正的 DATE
类型。您需要更改它以将 generate_series()
的结果转换为日期。您也只需要一个 generate_series()
而不是两个:
WITH gen_dates AS (
SELECT date_part('dow',d.dt) as dow,
dt::date as date
from generate_series('2017-11-01','2017-11-30', interval '1 day') as d(dt)
)
insert into days (dates, wtime)
SELECT date,
CASE
WHEN dow=1 then 8
WHEN dow=2 then 8
WHEN dow=3 then 8
WHEN dow=4 then 8
WHEN dow=5 then 8
WHEN dow=6 then 0
WHEN dow=0 then 0
ELSE 0
END as wtime
FROM gen_dates
无关,但是:您并不真的需要 CTE。您可以将插入简化为:
insert into days (dates, wtime)
SELECT dt::date,
CASE date_part('dow', dt)
WHEN 1 then 8
WHEN 2 then 8
WHEN 3 then 8
WHEN 4 then 8
WHEN 5 then 8
WHEN 6 then 0
WHEN 0 then 0
ELSE 0
END as wtime
FROM generate_series('2017-11-01','2017-11-30', interval '1 day') as d(dt);
请注意 CASE
语句的简短形式,您不必重复测试所针对的表达式。
也许您的问题是 CTE 和您的目标 table 同名。
另一个问题是您的 "date" 源列不是真正的 date
数据类型:
INSERT * INTO days
WITH days_cte AS (
SELECT
date_part('dow',generate_series('2017-11-01','2017-11-30', interval '1 day')) as dow,
to_char(generate_series('2017-11-01','2017-11-30', interval '1 day'),'YYYY-MM-DD') as date )
SELECT 0 as id, "date"::date,
CASE
WHEN dow=1 then 8
WHEN dow=2 then 8
WHEN dow=3 then 8
WHEN dow=4 then 8
WHEN dow=5 then 8
WHEN dow=6 then 0
WHEN dow=0 then 0
ELSE 0 END as wtime
FROM days_cte