在PostgreSQL 9.3我有以下表2個時間戳:如何合併時間戳列?
create table pref_users (
id varchar(32) primary key,
first_name varchar(64) not null,
last_name varchar(64),
female boolean,
avatar varchar(128),
city varchar(64),
mobile varchar(64),
login timestamp default current_timestamp,
logout timestamp,
last_ip inet,
vip timestamp, /* XXX can be NULL */
grand timestamp, /* XXX can be NULL */
mail varchar(256),
green integer,
red integer,
medals integer not null default 0
);
時間戳vip
和grand
表示如果遊戲的用戶已經支付了一定的privilleges - 直到這些日期。
當用戶連接到我的遊戲服務器,我打電話與OUT
參數以下過程:
create or replace function pref_get_user_info(
IN _id varchar,
OUT is_banned boolean,
OUT is_grand boolean,
OUT is_vip boolean,
OUT rep integer
) as $BODY$
begin
is_banned := exists(select 1 from pref_ban where id=_id);
if is_banned then
return;
end if;
select
grand > current_timestamp,
vip > current_timestamp,
into is_grand is_vip
from pref_users where id=_id;
if is_grand or is_vip then
return;
end if;
select
count(nullif(nice, false)) -
count(nullif(nice, true))
into rep
from pref_rep where id=_id;
end;
$BODY$ language plpgsql;
這確實工作得很好,但有時提供NULL
值到我的遊戲後臺程序(Perl腳本):
# select * from pref_get_user_info('OK674418426646');
is_banned | is_grand | is_vip | rep
-----------+----------+--------+-----
f | | | 126
(1 row)
我並不需要一個NULL
雖然(和它打印警告我的Perl腳本) - 我只是需要一個「真」或「假」值存在。
所以我曾嘗試:
select
coalesce(grand, 0) > current_timestamp,
coalesce(vip, 0) > current_timestamp,
into is_grand is_vip
from pref_users where id=_id;
但是這給了我錯誤:
# select * from pref_get_user_info('OK674418426646');
ERROR: COALESCE types timestamp without time zone and integer cannot be matched
LINE 2: coalesce(grand, 0) > current_timesta...
^
QUERY: select
coalesce(grand, 0) > current_timestamp,
coalesce(vip, 0) > current_timestamp,
is_vip
from pref_users where id=_id
CONTEXT: PL/pgSQL function pref_get_user_info(character varying) line 9 at SQL statement
所以我想在這裏做什麼嗎?
難道我真的要
select
coalesce(grand, current_timestamp - interval '1 day') > current_timestamp,
coalesce(vip, current_timestamp - interval '1 day') > current_timestamp,
into is_grand is_vip
from pref_users where id=_id;
或有可能是更好的方式(譬如「時代的開始」或「昨天」)?
UPDATE:
正如Clodo阿爾內託建議我已經試過(謝謝!):
select
coalesce(grand > current_timestamp, false),
coalesce(vip > current_timestamp, false),
into is_grand is_vip
from pref_users where id=_id;
但is_vip
爲NULL時vip
爲NULL:
# select * from pref_get_user_info('OK674418426646');
is_banned | is_grand | is_vip | rep
-----------+----------+--------+-----
f | t | |
(1 row)
而且當我嘗試以下任我得到語法錯誤:
select
coalesce(grand > current_timestamp, false),
coalesce(vip > current_timestamp, false),
into is_grand, is_vip
from pref_users where id=_id;
select
coalesce(grand > current_timestamp, false),
coalesce(vip > current_timestamp, false),
into (is_grand, is_vip)
from pref_users where id=_id;
怎麼能在這裏一次我SELECT
到2個變量?
在第一個版本作爲編輯,刪除之前的逗號「到」在第三行的端部。 –
哦,對,我很愚蠢(在vi編輯器中複製上面的行)。但是,這兩個變量之間的逗號呢?這兩種方法都可以在「psql」提示符下被接受,但是會產生不同的結果... –