パックされた日の文字列には 128 の可能な値しかありません (7 つのスロットと各スロットの 2 つの可能な値は 128 の可能性を意味します)。すべてのオプションをカバーするテーブルを生成し、そのテーブルに結合してアンパックされた文字列を取得します。このようなテーブルを非常に簡単に生成できるはずです。
packed | unpacked
----------+-----------
'0000000' | ''
'0000001' | 'Saturday'
...
'1000001' | 'Sunday, Saturday'
...
次に、満員日の列をこのテーブルに結合し、人に優しい文字列を取得するようにpacked
選択できます。unpacked
有限ドメイン上の関数は連想テーブルであり、ドメインが小さい場合は関数をテーブルとして簡単に実装できることに注意してください。
難しい方法で行う必要がある場合、これは 8.1 で機能しますが、これはかなり恐ろしいことであり、(1) そのように日を保存するべきではなく、(b) この種のフォーマットを処理する必要があることを納得させるはずです。データベースの外。実生活ではこのようなことはしません。制約のある 8.1 環境で機能する何かを考え出すことができるかどうかを確認したかったので、これを含めているだけです。あなたもできるだけ早くアップグレードしたいかもしれません.8.1はかなり長い間使用されており、もはやサポートされていません.
まず、結合する曜日名のテーブルが必要です。
create table days (num int not null, name varchar(9) not null);
insert into days (num, name) values (1, 'Sunday');
insert into days (num, name) values (2, 'Monday');
insert into days (num, name) values (3, 'Tuesday');
insert into days (num, name) values (4, 'Wednesday');
insert into days (num, name) values (5, 'Thursday');
insert into days (num, name) values (6, 'Friday');
insert into days (num, name) values (7, 'Saturday');
次に、コンマで区切られた文字列を結合するためのカスタム集計:
create function comma_join(t1 text, t2 text) returns text as $$
begin
if t1 is null or t2 is null then
return null;
elseif t1 = '' or t2 = '' then
return t1 || t2;
end if;
return t1 || ', ' || t2;
end;
$$ language plpgsql;
create aggregate group_comma_join(
sfunc = comma_join,
basetype = text,
stype = text,
initcond = ''
);
そして最後に、すべての醜さを隠すアンパック関数:
create function unpack_days(days_string text) returns text as $$
declare
s text;
begin
select group_comma_join(name)
from (
select name into s
from days d join generate_series(1, 7) n(num) on d.num = n.num
where substr(days_string, n.num, 1) = '1'
) dt;
return s;
end
$$ language plpgsql;
これで次のように言えます。
=> select unpack_days('0111110');
unpack_days
----------------------------------------------
Monday, Tuesday, Wednesday, Thursday, Friday
(1 row)
=> select unpack_days('0000000');
unpack_days
-------------
(1 row)