通过 PostgreSQL 为不在 From 子句中的 table 创建百分比列

Creating a percentage column to a table that is not in the From clause through PostgreSQL

我正在使用位于 here and here 的自行车共享数据集是其中的一个样本月。 我想获得每种会员类型每天的乘车百分比,所以我通过 PostgreSQL 应用了这个查询:

SELECT  Start_day,
        member_casual AS Membership,  
        COUNT(*) AS Trips_Count, 
        (COUNT(*) / (SELECT count(*) from rides)) AS Trips_percent, 
        AVG(duration) AS Average_Trip_Duration
FROM (SELECT member_casual,  
      ended_at - started_at AS duration, 
      EXTRACT(DOW from started_at) AS Start_day_num, 
      TO_CHAR(started_at,'DY') AS Start_day 
      FROM rides
     ) AS member_duration
GROUP BY Start_day, Start_day_num, member_casual 
ORDER BY Start_day_num, Trips_Count;

查询返回的所有字段都是正确的,除了 Trips_percent 它全是零!

我搜索了几个解决方案;我发现有人建议先通过 WITH 子句定义总和,然后在查询中使用它,如下所示:

WITH total AS 
    (SELECT COUNT(member_casual) AS records 
     FROM rides)
SELECT  Start_day,
        member_casual AS Membership,  
        COUNT(*) AS Trips_Count, 
        (COUNT(*) / total.records) AS Trips_percent, 
        AVG(duration) AS Average_Trip_Duration
FROM (SELECT member_casual,  
      ended_at - started_at AS duration, 
      EXTRACT(DOW from started_at) AS Start_day_num, 
      TO_CHAR(started_at,'DY') AS Start_day 
      FROM rides
     ) AS member_duration
GROUP BY Start_day, Start_day_num, member_casual 
ORDER BY Start_day_num, Trips_Count;

不幸的是,它给了我以下错误:

ERROR:  missing FROM-clause entry for table "total"
LINE 7:   (count(*) / total.records) AS Trips_percent, 
                      ^
SQL state: 42P01
Character: 178

是否因为主查询中的FROM子句没有引用WITH查询的table?

这两个查询有什么问题,我该如何解决?

我建议将其表述为 window 函数。但关键是避免整数除法:

SELECT Start_day,
       member_casual AS Membership,  
       COUNT(*) AS Trips_Count, 
       (COUNT(*) * 1.0 / SUM(COUNT(*)) OVER ()) AS Trips_percent, 
       AVG(duration) AS Average_Trip_Duration
FROM (SELECT member_casual,  
             ended_at - started_at AS duration, 
             EXTRACT(DOW from started_at) AS Start_day_num, 
             TO_CHAR(started_at,'DY') AS Start_day 
      FROM rides
     ) AS member_duration
GROUP BY Start_day, Start_day_num, member_casual 
ORDER BY Start_day_num, Trips_Count;