简体   繁体   English

SQL:通过分区聚合

[英]SQL: Aggregations over partition by

Query: Considering only Italian routes, for each category of goods and for each year查询:仅考虑意大利航线,针对每个商品类别和每年

  • select the average daily income for each month select 每个月的日均收入

  • the total monthly income since the beginning of the year自年初以来的月收入总额

SQL: SQL:

SELECT
  gc.GoodCategory,
  tm.Month,
  tm.Year,
  SUM(ro.Income) / COUNT(DISTINCT tm.Date),
  SUM(ro.Income) OVER (PARTITION BY gc.GoodCategory, tm.Year 
    ORDER BY tm.Month ROWS UNBOUNDED PRECEDING)

FROM FactRoutes ro,
     DimLocation dp,
     DimLocation ds,
     DimGoodCategory gc,
     DimTime tm

WHERE ro.DepartureID = dp.LocationID
    AND ro.DestinationID = ds.LocationID
    AND ro.GoodCategoryID = gc.GoodCategoryID
    AND ro.GoodTimeID = tm.GoodTimeID
    AND dp.State = 'Italy'
    AND ds.State = 'Italy'

GROUP BY gc.GoodCategory,
     tm.Month,
     tm.Year;

But facing the below error但面临以下错误

Column 'FactRoutes.Income' is invalid in the select list
because it is not contained in either an aggregate function
or the GROUP BY clause.

whats the better way to handle it?有什么更好的方法来处理它?

I think that you want:我认为你想要:

SELECT
  gc.GoodCategory,
  tm.Month,
  tm.Year,
  SUM(ro.Income) / COUNT(DISTINCT tm.Date),
  SUM(SUM(ro.Income)) OVER (PARTITION BY gc.GoodCategory, tm.Year ORDER BY tm.Month)
FROM FactRoutes ro
INNER JOIN DimLocation dp ON ro.DepartureID = dp.LocationID
INNER JOIN DimLocation ds ON ro.DestinationID = ds.LocationID
INNER JOIN DimGoodCategory gc ON ro.GoodCategoryID = gc.GoodCategoryID
INNER JOIN DimTime tm ON ro.GoodTimeID = tm.GoodTimeID
WHERE dp.State = 'Italy' AND ds.State = 'Italy'
GROUP BY gc.GoodCategory, tm.Month, tm.Year;

The main point is that, in order to make your query is not a valid aggregate query, you need to use an aggregate function within the window function, like SUM(SUM(ro.Income)) OVER (...) instead of just SUM(ro.Income) OVER(...) , so you get a window sum over the previous groups of records.要点是,为了使您的查询不是有效的聚合查询,您需要在 window function 中使用聚合 function function,而不是SUM(SUM(ro.Income)) OVER (...) SUM(ro.Income) OVER(...) ,因此您将获得 window 与先前记录的总和。

Other notable points:其他值得注意的点:

  • always use explicit joins (with the ON keyword) rather than old-school, implicit joins (with commas in the FROM clause), whose syntax has fallen out of favor for decades总是使用显式连接(使用ON关键字)而不是老式的隐式连接(在FROM子句中使用逗号),其语法已经失宠了几十年

  • ROWS UNBOUNDED PRECEDING is not needed; ROWS UNBOUNDED PRECEDING是不需要的; your window function has an ORDER BY clause so that's what it does anyway你的 window function 有一个ORDER BY子句,所以无论如何它就是这样做的

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

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