车辆装配数据合并重叠年份
Posted
技术标签:
【中文标题】车辆装配数据合并重叠年份【英文标题】:Vehicle Fitment Data Merge Overlapping Years 【发布时间】:2017-12-28 04:14:36 【问题描述】:我有一个关于产品的大型车辆装配信息数据集,每一个都在自己的行中。 我正在努力创建一个查询以仅选择每个重叠条目的最小和最大年份。 比如我有这样的数据:
fromyear toyear makename modelname submodelname wheelbase BedLength BedTypeName bodytype note1 Note2 note3 partterminologyname exppartno
2008 2012 Chevrolet Silverado 1500 LT NULL 78.00 Fleetside NULL Black NULL NULL Truck Bed Mat 37807
2010 2010 Chevrolet Silverado 1500 LT NULL 78.00 Fleetside NULL Black NULL NULL Truck Bed Mat 37807
2014 2017 Chevrolet Silverado 1500 LT NULL 78.00 Fleetside NULL Black NULL NULL Truck Bed Mat 37807
我不关心保留数据,因此我通过选择最小和最大年份将注意力转移到 UPDATE 查询上,但添加了类似
(SELECT MIN(p2.fromyear)
FROM prod AS p2
WHERE p1.fromyear > 0
AND p2.toyear >= p1.fromyear
AND p2.fromyear < p1.fromyear
AND ISNULL(p2.makename, '') = ISNULL(p1.makename, '')
AND ISNULL(p2.modelname, '') = ISNULL(p1.modelname, '')
AND ISNULL(p2.submodelname, '') = ISNULL(p1.submodelname, '')
AND ISNULL(FLOOR(p2.wheelbase), 0) = ISNULL(FLOOR(p1.wheelbase), 0)
AND ISNULL(FLOOR(p2.BedLength), 0) = ISNULL(FLOOR(p1.BedLength), 0)
AND ISNULL(p2.BedTypeName, '') = ISNULL(p1.BedTypeName, '')
AND ISNULL(p2.bodytype, '') = ISNULL(p1.bodytype, '')
AND ISNULL(p2.note1, '') = ISNULL(p1.note1, '')
AND ISNULL(p2.Note2, '') = ISNULL(p1.Note2, '')
AND ISNULL(p2.note3, '') = ISNULL(p1.note3, '')
AND ISNULL(p2.exppartno, '') = ISNULL(p1.exppartno, '')) AS newfrom
导致查询运行时间过长(从具有超过 150k 行的表中提取)。 在执行 UPDATE 合并年份后,我可以简单地删除任何重复的行。
所需结果将只返回此模型的两行,2008-2012 和 2014-2017
我最初的想法是简单地选择 MIN(fromyear) 和 MAX(toyear),但这给我留下了一个问题,即选择无效的 2013 年。
有没有一些简单的方法来制定一个查询来处理这样的重叠年份?我在搜索中找到的所有内容都不涉及匹配多列数据。
【问题讨论】:
如果您还可以向我们展示更新后的表格是什么样子(选择?),那将非常有帮助。目前尚不清楚您在这里实际想要做什么。 【参考方案1】:我建议加入一个日期表,其中包含如下连续年份列表(以涵盖源数据中的全部年份):
year
-----
...
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
...
因此,将源表连接到日期表 ON (year >= fromyear AND year <= toyear)
,会得到以下结果:
year fromyear toyear vehicle_descriptor
2008 2008 2012 Chevrolet...
2009 2008 2012 Chevrolet...
2010 2008 2012 Chevrolet...
2011 2008 2012 Chevrolet...
2012 2008 2012 Chevrolet...
2010 2010 2010 Chevrolet...
2014 2014 2017 Chevrolet...
2015 2014 2017 Chevrolet...
2016 2014 2017 Chevrolet...
2017 2014 2017 Chevrolet...
然后对行进行分组(或选择不同的)以消除重复的年份。 (我使用“vehicle_descriptor”作为源数据中唯一标识车辆的所有列的简写。)
在去重结果上,添加如下一列:
(year - ROW_NUMBER() OVER (PARTITION BY vehicle_descriptor ORDER BY year ASC) ) AS year_group
这会为每一年生成一个唯一的数字或连续的年数。
year fromyear toyear veicle_descriptor row_number year_group (year - row_number)
2008 2008 2012 Chevrolet... 1 2007
2009 2008 2012 Chevrolet... 2 2007
2010 2008 2012 Chevrolet... 3 2007
2011 2008 2012 Chevrolet... 4 2007
2012 2008 2012 Chevrolet... 5 2007
2010 2010 2010 Chevrolet... (this row removed as year 2010 is a duplicate)
2014 2014 2017 Chevrolet... 6 2008
2015 2014 2017 Chevrolet... 7 2008
2016 2014 2017 Chevrolet... 8 2008
2017 2014 2017 Chevrolet... 9 2008
最后,一旦你有了这个 year_group,只需按照你最初设想的方式对行进行分组,按 vehicle_descriptor 和 year_group,然后选择 MIN(year) 和 MAX(year)。
year_group 值没有特别意义,不会保留在最终结果中 - 它只是用来区分序列。它之所以有效,是因为它在年份序列中每次出现不连续时都会递增(并且它会根据不连续的数量递增)。
我希望我已经令人满意地解释了这一点。我不在我的台式电脑上,所以我都是手写的!如果有任何不清楚的地方,或者您需要代码示例,请告诉我,我会回复您。
【讨论】:
史蒂夫,这是非常有用的信息,也是拆分年份和删除重复项的好主意!我不知道的一个技巧是使用 OVER 和 PARTITION BY。这个想法需要一年 - ROW_NUMBER 是一个优雅的解决方案,可以帮助对年份范围内的差距进行分组!这与 3 个链式 CTE 的组合为我的问题提供了完整的解决方案。以上是关于车辆装配数据合并重叠年份的主要内容,如果未能解决你的问题,请参考以下文章