简体   繁体   English

如何通过在python的同一psql表中添加2列来获得结果

[英]How to get results by adding 2 columns in same psql table in python

I recently started learning about databases. 我最近开始学习数据库。 Now I am testing my skills on a database backed application in python. 现在,我正在使用python在数据库支持的应用程序上测试我的技能。 I have created 2 tables in database something like this 我已经在数据库中创建了2个这样的表

CREATE TABLE players
(
    id     SERIAL PRIMARY KEY,
    name   TEXT
);

CREATE TABLE matches 
(
    game  SERIAL,
    winner SERIAL REFERENCES players(id),
    loser SERIAL REFERENCES players(id)
);

I am tying to make a query to those to get results as playerid, name wins, matches in order something like (id, name, wins, matches) . 我想对这些查询进行查询,以获取诸如playerid,name wins,matches之类的结果,例如(id,name,wins,matches)。

I am using this code to do that 我正在使用此代码来做到这一点

SELECT id, name, count(matches.winner) as wins, 
 (count(matches.winner) + count(matches.loser)) as match 
  FROM players LEFT JOIN matches ON players.id = matches.winner 
  GROUP BY players.id ORDER BY wins

it seems it is not working please help me to solve this. 似乎无法正常工作,请帮助我解决此问题。

Thanks. 谢谢。

I have tried this code below 我已经在下面尝试过此代码

    DB = connect()
    c = DB.cursor()
    c.execute("""WITH
                   results AS (
                            select P.id,
                                   P.name,
                                   1     win
                            from   players P inner join matches M
                            on M.winner = P.id
                            union all
                            select P.id,
                                   P.name,
                                   0    win
                            from   players P inner join matches M
                            on M.loser = P.id)
                select id,
                       name,
                       sum(win)   wins,
                       count(*)   matches
                from   results
                group by id, name """)
    return c.fetchall()
    DB.close()

This code is not getting any data from the database instead it is returning just []. 此代码未从数据库获取任何数据,而是仅返回[]。 I have also tried to replacing my query string with 我也尝试过将查询字符串替换为

query = oldstring.replace(" ","_")
c.execute(query)

but it is also not worked. 但它也不起作用。 Please help me to solve this. 请帮我解决这个问题。

First, you probably don't want to use SERIAL data type for FK columns, as it is an autoincrementing integer type which is good for PK, but not suitable for FK, better stick with INTEGER . 首先,您可能不希望对FK列使用SERIAL数据类型,因为它是一种自动递增的整数类型,对PK有利,但不适用于FK,因此最好坚持使用INTEGER

Second, consider some constraints to enforce what we call business-rules. 第二,考虑一些约束以执行我们所谓的业务规则。 Are there always two players? 总是有两个球员吗? Is it realistic for match to have no winner or loser? 比赛没有赢家或输家是否现实? What if it ends with a tie? 如果以领带结尾怎么办?

Anyway, let's keep it simple for now and assume that any time two players face each other one of them emerges the winner while the other one loses. 无论如何,让我们暂时保持简单,并假设任何时候两名玩家相互面对时,其中一位就会成为赢家,而另一位则输掉。 So the total number of matches is wins + losses. 因此,比赛的总数为胜负。

WITH
  results AS (
    select P.id,
           P.name,
           1     win
    from   players P inner join matches M
    on M.winner = P.id
    union all
    select P.id,
           P.name,
           0    win
    from   players P inner join matches M
    on M.loser = P.id)
select id,
       name,
       sum(win)   wins,
       count(*)   matches
from   results
group by id, name

So, what is going on here: 所以,这是怎么回事:

  • WITH is a Common Table Expression . WITH公用表表达式 It is basically a named subquery. 它基本上是一个命名的子查询。 I used it here for readability. 我在这里使用它是为了提高可读性。 I could put subquery inside the FROM clause, but it looks much better this way. 我可以将子查询放在FROM子句中,但是用这种方法看起来要好得多。
  • You need to join players and matches somehow, but each row in matches references two players. 您需要以某种方式加入playersmatches ,但是matches每一行都引用了两名玩家。 Ok, then, we will join them twice. 好吧,那么我们将加入他们两次。
  • When you join on matches.winner you get one row for every match, and there is the winner in this row. 当您加入matches.winner ,每场matches.winner都会获得一行,并且在这一行中有赢家。 This is already enough to count wins, but there is absolutely no info on losses. 这已经足以计算获胜次数,但绝对没有损失信息。
  • Second query adds one more row for every game, but this time there is loser in this row. 第二个查询为每个游戏增加了一行,但这次在这一行中有输家。
  • UNION ALL combines results of two queries in one resultset. UNION ALL将两个查询的结果合并到一个结果集中。
  • But we need to be able to distinguish between rows with different outcomes. 但是我们需要能够区分结果不同的行。 The simpliest way is to sum numbers, so I set 1 for wins and 0 for losses. 最简单的方法是对数字求和,因此我将1设置为胜利,将0为失败。
  • Finally group rows now using GROUP BY and aggregate. 最后,现在使用GROUP BY行进行分组并进行汇总。

You can count losses in similar fashion. 您可以用类似的方式计算损失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM