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

これにより、ピボット関数を使用して、それに応じてデータを変更できます。まだそれに取り組んでいるので、どんな助けでも大歓迎です。

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

(最初の試みはうまくいきませんでした)これをコーディングする1つのクリーンな方法は次のとおりです。

    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 関数は別の方法ですが、私はこれに慣れていません。

(2回目の試行) これは機能します。

    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

CC fghj NULL

秘訣は、最初に順序付けられたリストを作成することでした。この場合、キーとして指定されたデータを使用しているように見えるため、ルックアップにはコードのみを使用しました(アイテムは実際には問題ではありませんでした)。結合接続を拡張する必要がある場合があります。次に、順序付けされたリストを使用して、順序が 6 番目より上にあるすべてのモノを除外します。これは、モノが実際に自然な順序である場合にのみ機能します。そうでない場合は、モノが何であるかを最初に見つけるために振り出しに戻ります。

于 2012-09-03T16:22:58.897 に答える