我正在努力将纸牌游戏比赛的分数(总是3人)保存到PotsgreSQL 8.4.9中
我几乎所有的东西都在那里(请在下面),只有两个小部分丢失了。
我创建了3个SQL表:
create table pref_users (
uid varchar(32) primary key,
first_name varchar(64),
female boolean,
avatar varchar(128)
}
create table pref_games {
gid serial,
rounds integer not null,
finished timestamp default current_timestamp
}
create table pref_scores (
uid varchar(32) references pref_users,
gid serial references pref_games, /* XXX serial ok here? */
money integer not null,
quit boolean
);
这里是我需要帮助的PL/pgSQL过程,请:
create or replace function pref_insert_scores(
_uid0 varchar, _money0 integer, _quit0 boolean,
_uid1 varchar, _money1 integer, _quit1 boolean,
_uid2 varchar, _money2 integer, _quit2 boolean,
_rounds integer) returns void as $BODY$
begin
insert into pref_games (rounds) values (_rounds);
-- XXX how do I get the _gid of this new game?
insert into pref_scores (uid, gid, money, quit)
values(_uid0, _gid, _money0, _quit0);
insert into pref_scores (uid, gid, money, quit)
values(_uid1, _gid, _money1, _quit1);
insert into pref_scores (uid, gid, money, quit)
values(_uid2, _gid, _money2, _quit2);
end;
$BODY$ language plpgsql;
然后,我需要一些帮助才能加入第一张表中的first_name、女性、阿凡达数据的得分,这样我就可以在网页上的一张桌子上显示过去7天玩过的游戏列表:
01.12.2011 Alice $10 Bob $20 Charlie -$30 17 rounds
01.12.2011 Alice $0 (quit) Bob $20 Charlie -$20 5 rounds
更新:
有了穆的帮助太短了,现在我的表格里满是数据,但仍然不知道如何列出一个球员所做的所有比赛--连同他的两个对手和他们的分数。
我有一张桌子,里面放着所有的游戏:
# select * from pref_games limit 5;
gid | rounds | finished
-----+--------+----------------------------
1 | 10 | 2011-10-26 14:10:35.46725
2 | 12 | 2011-10-26 14:34:13.440868
3 | 12 | 2011-10-26 14:34:39.279883
4 | 14 | 2011-10-26 14:35:25.895376
5 | 14 | 2011-10-26 14:36:56.765978
在这里,我有3名球员(以及他们的分数)参加了第3场比赛:
# select * from pref_scores where gid=3;
uid | gid | money | quit
-----------------------+-----+-------+------
OK515337846127 | 3 | -37 | f
OK40798070412 | 3 | -75 | f
MR2871175175044094219 | 3 | 112 | f
这些都是玩家用uid =DE9411玩的游戏:
# select * from pref_scores where id='DE9411';
uid | gid | money | quit
--------+-----+-------+------
DE9411 | 43 | 64 | f
DE9411 | 159 | -110 | f
DE9411 | 224 | 66 | f
DE9411 | 297 | -36 | f
DE9411 | 385 | 29 | f
DE9411 | 479 | -40 | f
DE9411 | 631 | -14 | f
DE9411 | 699 | 352 | f
DE9411 | 784 | -15 | f
DE9411 | 835 | 242 | f
但是我如何在上面的结果中列出其他两名球员的成绩呢?
发布于 2011-10-26 08:03:25
你不想serial
在pref_scores
,只有int
create table pref_scores (
uid varchar(32) references pref_users,
gid int references pref_games, /* XXX serial ok here? */
money integer not null,
quit boolean
);
你想要使用INSERT ... RETURNING ... INTO
create or replace function pref_insert_scores(
_uid0 varchar, _money0 integer, _quit0 boolean,
_uid1 varchar, _money1 integer, _quit1 boolean,
_uid2 varchar, _money2 integer, _quit2 boolean,
_rounds integer) returns void as $BODY$
declare
_gid int;
begin
insert into pref_games (rounds) values (_rounds) returning gid into _gid;
-- etc...
发布于 2011-10-26 09:08:07
此查询可用于获取当前架构所需的列表。但是,有了这么多的连接,性能可能就不那么好了。由于您知道始终有3个用户,这取决于该表的预期大小,因此您可能需要测试性能,以确定是否有一个带有用户信息非规范化的游戏表。
select g.finished, u1.uid u1, s1.money m1, s1.quit q1, u2.uid u2, s2.money m2, s2.quit
q2, u3.uid u3, s3.money m3, s3.quit q3, g.rounds
from pref_games g
inner join pref_scores s1 on s1.gid = g.gid
inner join pref_scores s2 on s2.gid = g.gid and s2.uid > s1.uid
inner join pref_scores s3 on s3.gid = g.gid and s3.uid > s2.uid
inner join pref_users u1 on s1.uid = u1.uid
inner join pref_users u2 on s2.uid = u2.uid
inner join pref_users u3 on s3.uid = u3.uid
and g.finished > CURRENT_DATE - interval '1 week'
发布于 2011-10-26 19:57:06
在队伍中:
finished timestamp default current_timestamp
我强烈建议用
finished timestamptz default current_timestamp
由于这样允许在GMT中存储实际日期/时间的夏时制更改,因此它也更适合于国际化。
来自pg9.1.1手册“8.5.日期/时间类型”:
..。
注意: SQL标准要求只写时间戳就等于没有时区的时间戳,PostgreSQL尊重这种行为。( 7.3之前的发布将其视为带有时区的时间戳。)时间戳被接受为带有时区时间戳的缩写;这是一个PostgreSQL扩展。
..。
对于带有时区的时间戳,内部存储的值总是以UTC (通用协调时间,传统上称为格林尼治标准时间,GMT)为单位。指定了显式时区的输入值将使用该时区的适当偏移量转换为UTC。如果输入字符串中没有指定时区,则假定它位于由系统时区参数指示的时区,并使用时区偏移量将其转换为UTC。
当输出带有时区值的时间戳时,它总是从UTC转换为当前的时区区域,并显示为该区域中的本地时间。要查看另一个时区中的时间,可以更改时区或使用AT时区构造(参见9.9.3节)。
..。
https://stackoverflow.com/questions/7899995
复制相似问题