使用SSIS,我如何找到人口最多的城市?

时间:2011-11-10 14:24:12

标签: sql-server ssis

我有一个数据流任务,其信息看起来像这样:

Province | City    | Population
-------------------------------
Ontario  | Toronto | 7000000
Ontario  | London  |  300000
Quebec   | Quebec  |  300000
Quebec   | Montreal| 6000000

如何使用聚合转换来获得每个省人口最多的城市:

Province | City    | Population
-------------------------------
Ontario  | Toronto | 7000000
Quebec   | Montreal| 6000000

如果我将“省”设置为“分组依据”列,将“人口”设置为“最大”汇总,我该如何处理“城市”列?

2 个答案:

答案 0 :(得分:3)

完全同意@PaulStock认为聚合最好留给源系统。 SSIS中的聚合是一个完全阻塞的组件,就像排序一样,我already made my argument on that point

但有时候在源系统中执行这些操作是行不通的。我能想到的最好的方法是基本上对数据进行双重处理。是的,ick但是我从来没有找到过通过未受影响的列的方法。对于Min / Max场景,我希望将其作为一个选项,但显然像Sum这样的东西会让组件很难知道它所关联的“源”行是什么。

2005

2005年的实施将如下所示。你的性能不会很好,事实上只有好几个数量级,因为除了必须重新处理你的源数据之外你还会有所有这些阻塞变换。

2005 aggregate

合并加入 2005 Merge Inner Join

2008

2008年,您可以选择使用Cache Connection Manager,这有助于消除阻止变换,至少在重要的地方,但您仍然需要支付双重处理源数据的成本。

将两个数据流拖到画布上。第一个将填充缓存连接管理器,并且应该在聚合发生的位置。

Warm cache connection manager

现在缓存中包含聚合数据,在主数据流中删除查找任务并对缓存执行查找。

常规查找标签

General lookup tab

选择缓存连接管理器

Connection manager lookup tab

映射相应的列

Columns lookup tab

非常成功 Great success 2008 data flow

脚本任务

我能想到的第三种方法,即2005年或2008年,就是把它写成自己的。作为一般规则,我试图避免脚本任务,但这是一个可能有意义的情况。您需要将其设为asynchronous script transformation,但只需处理您的聚合。需要维护更多代码,但您可以省去重新处理源数据的麻烦。

最后,作为一般警告,我将调查关系对您的解决方案的影响。对于这个数据集,我希望像Guelph这样的东西突然膨胀并与多伦多联系,但如果确实如此,该包应该做什么?现在,安大略省两个都会产生两排,但这是预期的行为吗?当然,脚本允许您定义在关系情况下发生的情况。您可以通过缓存“正常”数据并将其用作查找条件并使用聚合来拉回其中一个关系,从而使2008解决方案成为可能。 2005可以通过将聚合作为合并连接的左源来实现相同的目标

编辑

杰森霍纳在评论中有个好主意。另一种方法是使用多播转换并在一个流中执行聚合并将其重新组合在一起。我无法弄清楚如何使它与联合使用,但我们可以使用排序和合并连接,就像上面一样。这可能是一种更好的方法,因为它为我们省去了重新处理源数据的麻烦。

enter image description here

答案 1 :(得分:0)

您可以使用SQL查询代替使用聚合转换吗?

SELECT
    p.province,
    p.city,
    p.[population]
FROM
    temp_pop P
    JOIN ( SELECT
            province,
            [population] = MAX([POPULATION])
           FROM
            temp_pop
           GROUP BY
            province
         ) AS M ON p.province = M.province AND
                   p.[population] = M.[population]