反转/吹掉GROUP BY

时间:2012-04-12 18:31:51

标签: sql sql-server-2008 tsql

我正在处理按项目编号和计数分组的数据。需要将具有count > 2的每条记录分成单个记录,并在该级别与不同的数据集进行比较。

数据看起来像这样(它停留在这种格式中。这是客户发送它的唯一方式。):

OwnerNumber ItemCode    ItemNumber  CountOfItems
1234    Item1   Item1-001   3
1234    Item1   Item1-002   1
1234    Item1   Item1-003   2
1234    Item2   Item2-001   1

我需要像这样格式化的数据(动态而无需对CountOfItems的值进行硬编码):

OwnerNumber ItemCode    ItemNumber  
1234    Item1   Item1-001
1234    Item1   Item1-001
1234    Item1   Item1-001
1234    Item1   Item1-002
1234    Item1   Item1-003
1234    Item1   Item1-003
1234    Item2   Item2-001

出于某种原因,我无法用干净的方式绕过这个(或任何方式)。

3 个答案:

答案 0 :(得分:4)

您可以使用公用表表达式进行管理

WITH CTE AS (
    SELECT OwnerNumber,ItemCode,ItemNumber,CountOfItems FROM table

    UNION ALL SELECT OwnerNumber,ItemCode,ItemNumber,CountOfItems-1
    FROM CTE
    WHERE CountOfItems >= 2
)
SELECT OwnerNumber,ItemCode,ItemNumber
FROM CTE
ORDER BY ItemNumber
OPTION (MAXRECURSION 0);

修改

添加MAXRECURSION来处理CountOfItems超出默认最大递归的情况,如Dev_etter所指出

答案 1 :(得分:3)

嗯......我想我喜欢递归CTE:

WITH Data (OwnerNumber, ItemCode, ItemNumber, CountOfItems) as (
           SELECT OwnerNumber, ItemCode, ItemNumber, CountOfItems
           FROM OriginalTable
           UNION ALL
           SELECT OwnerNumber, ItemCode, ItemNumber, CountOfItems - 1
           FROM Data
           WHERE CountOfItems > 1)
SELECT OwnerNumber, ItemCode, ItemNumber
FROM Data
ORDER BY OwnerNumber, ItemCode, ItemNumber

答案 2 :(得分:3)

您可以使用下面的查询避免递归,我认为会更有效率。这里,表N是具有至少与最大CountOfItems值一样多的行的任何表。

这是一个罕见的查询示例,其中没有ORDER BY的TOP不是一个坏主意。

select
  OwnerNumber,
  ItemCode,
  ItemNumber
from t
cross apply (
  select top (CountOfItems) null
  from N
 ) as N(c)