Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.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
带默认值的PostgreSQL查询数据聚合_Sql_Postgresql - Fatal编程技术网

带默认值的PostgreSQL查询数据聚合

带默认值的PostgreSQL查询数据聚合,sql,postgresql,Sql,Postgresql,我是SQL新手,尝试从在线教程中学习基础知识。我被一个问题难住了,希望你能给我一些建议 目前,目标是使用查询为锦标赛创建一个玩家站立表。我有两张桌子;球员和比赛 tournament=> select * from players; id | name ----+------------------ 19 | Melpomene Murray 20 | Randy Schwartz 46 | Ricardo (3 rows) tournament=&g

我是SQL新手,尝试从在线教程中学习基础知识。我被一个问题难住了,希望你能给我一些建议

目前,目标是使用查询为锦标赛创建一个玩家站立表。我有两张桌子;球员和比赛

tournament=> select * from players;
 id |       name       
----+------------------
 19 | Melpomene Murray
 20 | Randy Schwartz
 46 | Ricardo
(3 rows)


tournament=> select * from matches;
 winner_id | loser_id 
-----------+----------
        19 |       20
(1 row)
我需要汇总胜利和比赛来完成此操作:

 id |       name       | wins | p_matches 
----+------------------+------+-----------
 19 | Melpomene Murray |    1 |         1
 20 | Randy Schwartz   |    0 |         1
 46 | Ricardo          |    0 |         0
现在这是我最好的猜测:

tournament=> select players.id, players.name, subq.wins, subq2.p_matches from players,
(select players.id,count(players.id) as wins from players,matches 
where matches.winner_id = players.id group by players.id) as subq,
(select count(*) as p_matches from matches) as subq2;

 id |       name       | wins | p_matches 
----+------------------+------+-----------
 19 | Melpomene Murray |    1 |         1
 20 | Randy Schwartz   |    1 |         1
 46 | Ricardo          |    1 |         1
很大一部分问题源于我的子查询。当我单独运行它时,由于条件限制,我得到的是一行。我想让它列出所有ID,并没有赢行保持零

tournament=> select players.id,count(players.id) as wins from players,matches 
where matches.winner_id = players.id group by players.id;
 id | wins 
----+------
 19 |    1
我听说coalesce可以做这样的事情,但我还没能把它变为魔法。想法?

可能是这样的:

t=# with a as (
select p.*, w.w wins, coalesce(w.w, l.l) p_m
from players p
left outer join matches w on w.w = p.id
left outer join matches l on l.l = p.id
)
select id,name, count(wins), count(p_m)
from a
group by id, name
order by id;
 id |       name        | count | count
----+-------------------+-------+-------
 19 |  Melpomene Murray |     1 |     1
 20 |  Randy Schwartz   |     0 |     1
 46 |  Ricardo          |     0 |     0
(3 rows)

一种简单的方法是在select子句中使用子查询:

select 
  id, 
  name,
  (select count(*) from matches m where p.id = m.winner_id) as wins,
  (select count(*) from matches m where p.id in (m.winner_id, m.loser_id)) as p_matches
from players p
order by id;

还有一个问题,我不确定哪一个性能更好(可能比多个子查询更好)

这将选择所有播放器记录,并左键联接matches表(无论播放器id是否存在),然后对结果进行分组,在这种情况下,可以使用诸如count之类的聚合函数


第一个count aggregate函数将只计算winners列(赢)中具有玩家id的行,第二个函数将对任何一列中的行进行计数。

麻烦您逐一解释一下,好吗?我对整个shebang很陌生,我想了解您的查询是如何工作的。例如,我从未见过一个以命令“with”而不是“select”开头的查询。我可以按照这个查询的逻辑进行操作,但我认为我无法从查询的该部分访问播放器。相反,postgres认为我做不到:错误:模式“p”不存在,对不起,我错过了关键字中的
,所以PostgreSQL可能把
p.id(m.winner\u id,m.loser\u id)
作为一个函数,所以
p
将是模式。这似乎很有效,我也很好地理解了它的要点。非常感谢。
select p.id,
       p.name, 
       count(case when m.winner_id = p.id then 1 end) won, 
       count(m.*) total 
from players p 
left join matches m 
on m.winner_id = p.id 
or p.id = m.loser_id 
group by p.id, p.name;