0

我有一个返回这样的项目的查询

Item    --  Code   --  Thing
------------------------------
Item A  --  Code A --  Thing 1
Item A  --  Code A --  Thing 2
Item A  --  Code A --  Thing 3
Item A  --  Code A --  Thing 4
Item B  --  Code B --  Thing x
Item B  --  Code B --  Thing y
Item C  --  Code C --  Thing z
Item C  --  Code C --  Thing a
Item C  --  Code C --  Thing b
Item C  --  Code C --  Thing c

我想把它变成这样的东西

Item    --  Code   --  Thing 1 -- Thing 2 -- Thing 3 -- Thing 4 -- Thing 5
---------------------------------------------------------------------------
Item A  --  Code A --  Thing 1 -- Thing 2 -- Thing 3 -- Thing 4 -- NULL
Item B  --  Code B --  Thing x -- Thing y -- NULL    -- NULL    -- NULL
Item C  --  Code C --  Thing a -- Thing b -- Thing c -- Thing d -- NULL

任何超过 5 的项目都可以忽略。


更新:

通过添加“ROW_NUMBER() over (Partition by Table.Id order by Table2.Id)”在我的查询中,我现在得到:

Item    --  Code   --  Thing  -- Index
---------------------------------------
Item A  --  Code A --  Thing 1 -- 1
Item A  --  Code A --  Thing 2 -- 2
Item A  --  Code A --  Thing 3 -- 3
Item A  --  Code A --  Thing 4 -- 4
Item B  --  Code B --  Thing x -- 1
Item B  --  Code B --  Thing y -- 2
Item C  --  Code C --  Thing z -- 1
Item C  --  Code C --  Thing a -- 2
Item C  --  Code C --  Thing b -- 3
Item C  --  Code C --  Thing c -- 4

这允许我使用 Pivot 函数并相应地更改数据。仍在努力,因此非常感谢任何帮助。

4

2 回答 2

1

您可以使用 PIVOT 运算符

这是针对类似问题的示例查询

SELECT *
FROM
    (
    SELECT Contact_Id AS CT
          , [Age]
          , [Sex]
          , [State]
          , [Country]
          , [Keyword]
          , [Married]
          , [Kids]
          , [Car]
     FROM
         (SELECT c.PropertyName
               , c.ValueString
               , c.Contact_Id
          FROM
              ContactProfiles c) AS ctp
         PIVOT (max(ctp.ValueString) FOR PropertyName IN ([Age], [Sex], [State], [Country], [Keyword], [Married], [Kids], [Car])) AS PivotTable
         ) AS pvt

WHERE
    pvt.[Age] > 18
于 2012-09-03T16:46:26.813 回答
0

(第一次尝试不起作用)一种简洁的编码方法是:

    SELECT
        Item,
        Code,
        Thing1 = Case When Thing = 'Thing 1' Then 'Thing 1' Else Null End,
        Thing2 = Case When Thing = 'Thing 2' Then 'Thing 2' Else Null End,
        Thing3 = Case When Thing = 'Thing 3' Then 'Thing 3' Else Null End,
        Thing4 = Case When Thing = 'Thing 4' Then 'Thing 4' Else Null End,
        Thing5 = Case When Thing = 'Thing 5' Then 'Thing 5' Else Null End
   FROM [Items]
   WHERE Thing BETWEEN 'Thing 1' AND 'Thing 5' -- preselection should improve performance
   GROUP BY 
        Item,
        Code,
        Thing1 = Case When Thing = 'Thing 1' Then 'Thing 1' Else Null End,
        Thing2 = Case When Thing = 'Thing 2' Then 'Thing 2' Else Null End,
        Thing3 = Case When Thing = 'Thing 3' Then 'Thing 3' Else Null End,
        Thing4 = Case When Thing = 'Thing 4' Then 'Thing 4' Else Null End,
        Thing5 = Case When Thing = 'Thing 5' Then 'Thing 5' Else Null End

之所以有效,是因为您有一个已知的、有限数量的要旋转的列。PIVOT 功能是另一种方式,但我不熟悉这种方式。

(第二次尝试)这行得通!

    DECLARE @Items TABLE
    (
        Item    char(1),
        Code    char(1),
        Thing   char(1)
    )
    INSERT INTO @Items
    SELECT 'A', 'A', '1'
    UNION
    SELECT 'A', 'A', '2'
    UNION
    SELECT 'A', 'A', '3'
    UNION
    SELECT 'A', 'A', '4'
    UNION
    SELECT 'B', 'B', 'x'
    UNION
    SELECT 'B', 'B', 'y'
    UNION
    SELECT 'C', 'C', 'f'
    UNION
    SELECT 'C', 'C', 'g'
    UNION
    SELECT 'C', 'C', 'h'
    UNION 
    SELECT 'C', 'C', 'j'

    SELECT
        Items.Item,
        Items.Code,
        Thing1 = Max(Case When OrderedItems.ThingPlace = 1 Then OrderedItems.Thing Else Null End),
        Thing2 = Max(Case When OrderedItems.ThingPlace = 2 Then OrderedItems.Thing Else Null End),
        Thing3 = Max(Case When OrderedItems.ThingPlace = 3 Then OrderedItems.Thing Else Null End),
        Thing4 = Max(Case When OrderedItems.ThingPlace = 4 Then OrderedItems.Thing Else Null End),
        Thing5 = Max(Case When OrderedItems.ThingPlace = 5 Then OrderedItems.Thing Else Null End)
    FROM @Items Items
        LEFT OUTER JOIN 
        (
            SELECT
                Code, Thing, 
                ThingPlace = Row_Number() OVER (PARTITION BY Code ORDER BY Thing)
            FROM @Items
            GROUP BY Code, Thing
        ) OrderedItems
            ON OrderedItems.Code = Items.Code
    WHERE OrderedItems.ThingPlace Is Null OR OrderedItems.ThingPlace <= 5
    GROUP BY
        Items.Item,
        Items.Code

结果:

AA 1 2 3 4 空

BB xy NULL NULL NULL

抄送 fghj 空

诀窍是首先建立一个有序的列表。我只使用了代码进行查找,因为在这种情况下,给定的数据是关键(项目并不重要)。您可能必须扩展连接连接。然后使用有序列表,我按顺序排除第六位以上的所有事物。这仅在事物实际上是自然顺序时才有效 - 否则它会回到平方,首先找出事物是什么。

于 2012-09-03T16:22:58.897 回答