2

一意の ID を持つテーブル項目があります: itemId, … 行の例: '3506', …</p>

次の列を持つテーブル ItemProperties があります: itemId、datecreated、datemodified、property1、property2、property3、property4、property5

行の例: '3506'、'2012…'、'2012…'、'prop1'、'prop2'、'prop3'、'prop4'、'prop5'</p>

ItemProperties テーブルのすべての行を、次の列を持つ NewItemProperties テーブルの 5 つの個別の行に分割する必要があります: itemId、datecreated、datemodified、propertynumber、property

5 行の例:

‘3506’, ‘2012…’, ‘2012…’, 1, ‘prop1’

‘3506’, ‘2012…’, ‘2012…’, 2, ‘prop2’

‘3506’, ‘2012…’, ‘2012…’, 3, ‘prop3’

‘3506’, ‘2012…’, ‘2012…’, 4, ‘prop4’

‘3506’, ‘2012…’, ‘2012…’, 5, ‘prop5’

制約: - Items テーブルに存在しない itemId を持つ ItemProperties は処理されません。

  • NewItems テーブルに既にある項目 (id =id および propertynumber=property1~5 列の番号) は、このプロセスによって上書き/更新されるべきではありません

  • Microsoft SQL Server 2008 R2

  • ItemProperties テーブルの約 800000 行

現時点で私が持っている非常に遅い解決策:

...

DECLARE c CURSOR read_only FOR SELECT * from ItemProperties

DECLARE @ID varchar(14), @CREA datetime, …

OPEN  c     

FETCH NEXT FROM c INTO @ID, @CREA, @MODI, @COL, @SIZE, @PAT, @YEAR, @ITEM

WHILE (@@fetch_status <> -1)

BEGIN

    IF (@@fetch_status <> -2)

    BEGIN
         select * from Items where itemId = @ID
         if @@ROWCOUNT = 0
               BEGIN
                    GOTO Fetch_Next
               END
         select * from ItemProperties where itemId = @ID AND propertynumber = 1
         if @@ROWCOUNT = 0
               INSERT INTO NewItemProperties
               VALUES(@ID, '1', @COL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
         select * from ItemProperties where itemId = @ID AND propertynumber = 2
         if @@ROWCOUNT = 0
               INSERT INTO NewItemProperties
               VALUES(@ID, '2', @SIZE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
     …

      END
    Fetch_Next:
    FETCH NEXT FROM c INTO @ID, @CREA, @MODI, @COL, @SIZE, @PAT, @YEAR, @ITEM
...

作成日と変更日を削除することで fetch ステートメントを最適化できますが、思いつくのはこれだけです。これをピボット解除クエリに適合させることができませんでした。基本的に、カーソルよりも速いものは何でも助けてくれます。すべてのアイデアを歓迎します。ありがとうございました。

4

3 に答える 3

2

これを試して

INSERT INTO NewItemProperties
SELECT itemId, '1', property1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
FROM ItemProperties 
UNION ALL
SELECT itemId, '2', property2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
FROM ItemProperties
......
UNION ALL
SELECT itemId, '5', property5, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
FROM ItemProperties
于 2012-12-17T19:56:36.240 に答える
1

これを に収めることができないとあなたが述べた理由がわかりませんUNPIVOTUNPIVOTただし、 を使用してデータを変換し、それを新しいテーブルに挿入できるはずです。WHERE内部クエリに任意の句条件を追加できます。重要なのUNPIVOTは、データが同じデータ型であることです。したがって、必要に応じて、サブクエリ内のデータを同じデータ型にキャストする必要がある場合があります。

insert into NewItemProperties(yourCcolsHere)
select itemid,
  datecreated, 
  datemodified,
  replace(col, 'property', '') col,
  value
from
(
 -- perform any datatype conversions here
  select i.itemid,
    p.datecreated,
    p.datemodified,
    p.property1, 
    p.property2, 
    p.property3, 
    p.property4, 
    p.property5
  from items i
  inner join ItemProperties p
    on i.itemid = p.itemid
) src
unpivot
(
  value
  for col in (property1, property2, property3,
              property4, property5)
) unpiv

デモで SQL Fiddle を参照してください

この関数は、クエリUNPIVOTと同じ機能を実行します。UNION ALL

insert into NewItemProperties(yourCcolsHere)
select i.itemid,
    p.datecreated,
    p.datemodified,
    1 PropNumber,
    p.property1 value 
from items i
inner join ItemProperties p
  on i.itemid = p.itemid
union all
select i.itemid,
    p.datecreated,
    p.datemodified,
    2 PropNumber,
    p.property2 value
from items i
inner join ItemProperties p
  on i.itemid = p.itemid -- add more queries for the other properties

デモで SQL Fiddle を参照してください

于 2012-12-17T19:48:25.507 に答える
0

これを行うには、挿入するすべてのものを返すクエリを定義してから、それらを挿入します。

with toinsert as (
     select ip.itemid, datecreated, datemodified, num as propertynumber
            (case when num = 1 then property1
                  when num = 2 then property2
                  when num = 3 then property3
                  when num = 4 then property4
                  when num = 5 then property5
             ) as property
     from ItemProperties ip cross join
          (select 1 as num union all select 2 union all select 3 union all select 4 union all select 5
          ) nums left outer join
          NewItemProperties nip
          on ip.itemid = nip.itemid and
             nums.num = nip.propertynumber
     where nip.itemid is null
    )
insert into NewItemProperties (itemid, datecreated, datemodified, propertynumber, property)
    select *
    from toinsert
于 2012-12-17T19:51:25.580 に答える