我正在学习SQL(自学)。我正在尝试编写一个可执行的postgres SQL查询来回答此问题:根据原籍城市(名称),计算出付款的行程百分比 比该城市的出行平均要高出至少10%。
上下文:1)已完成的旅程被定义为在租金表中状态为“已完成”的旅程。 2)仅考虑最近30天的行程。
我从什么开始(希望看起来不错)
SELECT n.name, r.origin_id, SUM(r.fare_dollars), AVG(r.fare_dollars), count(r.id)
FROM rentals r, neighborhood n
LEFT JOIN r ON r.origin_id = n.id
GROUP BY n.name;
在正确的轨道上?!
我需要您的帮助(如果我对这种方法是正确的):
该问题将要求我执行一个子查询,该查询将拉出所有记录以查看其与平均票价的比较。然后,我需要编写另一个查询,告诉我哪些游乐设施比平均票价高出10%。
我期待看到您可能提供的任何见解!请让我知道是否可以提供其他信息。
谢谢。
答案 0 :(得分:0)
您正在朝正确的方向思考,但是您的查询技能还没有,对吧?我将尽我所能进行解释,希望您能继续学习(如果不能,请随时提出。)
因此,首先,您需要知道每个出发地的平均票价是多少:
SELECT n.id, n.name, AVG(r.fare_dollars) AS average_fare
FROM neighborhood n
JOIN rentals r
ON r.origin_id = n.id
GROUP BY n.id, n.name
这是一个相当简单的查询,尽管通常在这里您不需要id。不过,我们将使用此查询与各个游乐设施进行比较,因此我们将其加入到我们的租金表中:
SELECT avg_per_neighborhood.name
, SUM(CASE
WHEN r.fare_dollars >= avg_per_neighborhood.average_fare * 1.1 THEN 1.0
ELSE 0
END) / COUNT(*) AS percAbove110
FROM rentals r
JOIN (SELECT n.id, n.name, AVG(r.fare_dollars) AS average_fare
FROM neighborhood n
JOIN rentals r
ON r.origin_id = n.id
GROUP BY n.id, n.name) avg_per_neighborhood
ON r.origin_id = avg_per_neighborhood.id
GROUP BY avg_per_neighborhood.name
有趣的部分当然是百分比比平均部分高10%以上;因此,我们首先确定单个租金是否高于联合平均* 1.1(或平均租金的110%),如果返回1,否则返回0-即{{1} }语句。我们将每个街区(CASE
)的总和除以该街区的游乐设施总数(SUM(CASE ... END)
),然后得出百分比。
此查询可以使用窗口函数进行一些重写:
COUNT(*)
在这里,SELECT subq.NAME
, SUM(subq.isHigherThan110avg) / COUNT(*) AS percAbove110
FROM (SELECT n.NAME
, CASE
WHEN r.fare_dollars > 1.1 * AVG(r.fare_dollars) OVER (PARTITION BY n.id) THEN 1.0
ELSE 0
END AS isHigherThan110avg
FROM neighborhood n
JOIN rentals r
ON r.origin_id = n.id
) subq
GROUP BY subq.name
子查询使用subq
窗口函数与平均内联进行比较,而外部查询只是聚合结果。
您当然需要应用自己的过滤器,例如已完成并持续30天,但我希望您能掌握要点。