1

次のようなテーブルがあります。

私のテーブル

私はこのようなものを手に入れるのが好きです:

私の結果表

「Property」で始まる行は、Property 列に移動します。「Location」で始まる行は「Location」列に移動し、「error」で始まる行は「ErrorMessage」列に移動します。ここのテーブルには、親子のようなデータが含まれています。たとえば、プロパティ X の場所は「abc」で、2 つのエラー「1234」と「5678」があります。

これまでのコメントに基づいて、さらに情報を追加します。

Aaron Bertrand の質問: Q1.ROWID がシーケンシャルであることを完全に信頼できますか?

A1.Rowidは順次増加していますが、常に1の順であるとは限りません。

例を見てみましょう。プロパティ X は rowid = 1 から始まり、プロパティ Y は 8 から始まります。プロパティ X のすべては、rowid 1 から 7 の間にあります。別のレベルに進むと、場所 abc は 2 から始まり、「def」は 5 から始まります。場所「abc」のすべてのエラー' は、rowid 3 から 4 の間になります。

Q2. また、場所とプロパティの組み合わせに対して、データ セットは 1 つしかありませんか? または、行 15 が再度プロパティ X であり、行 16 がプロパティ abc であるなどの可能性はありますか?

A2. プロパティと場所の組み合わせのデータ セットは 1 つだけです。したがって、Property X - Location abc が行 2 にある場合、後でテーブルに表示されることはありません。

詳細: ここの例では、限られた量の行しかありません。実際のテーブルには、これよりもはるかに多くの行があります。

これまでのところ、WHILE ループを使用して結果を得ることができました。行ごとに実行せずにこれを行う別の方法があるかどうか疑問に思っています。SQL 2008 R2 を使用しています。

4

5 に答える 5

1

これは 1 つのクエリで実行できます。まず、データを 3 つの部分 (プロパティ、場所、エラー) に分割し、親 ID を特定します。最後に、通常の結合を使用して結果を作成します。

with P as (
  select ID, ColumnDesc 
  from MyTable P
  where columnDesc like 'Property %'
),
L as (
  select ID, ColumnDesc, (Select MAX(P.id) from P where P.ID<L.ID ) as ParentID 
  from MyTable L
  where columnDesc like 'Location %'
),
E as (
  select ID, ColumnDesc, (Select MAX(L.id) from L where L.ID<E.ID ) as ParentID 
  from MyTable E
  where columnDesc like 'error %'
)
select 
  P.ColumnDesc as Property,
  L.ColumnDesc as Location,
  E.ColumnDesc as Error
FROM p
JOIN L ON (L.ParentId = P.ID)
JOIN E ON (E.ParentID = L.ID)
ORDER BY P.ID, L.ID, E.ID
于 2013-11-14T19:31:12.213 に答える
0

TSQL

WITH
source AS
(
  SELECT 1 AS id,'Property X' AS columnDesc
  UNION ALL SELECT 2 AS id,'Location abc'
  UNION ALL SELECT 3 AS id,'error 1234'
  UNION ALL SELECT 4 AS id,'error 3456'
  UNION ALL SELECT 5 AS id, 'Location def'
  UNION ALL SELECT 6 AS id,'error 1234'
  UNION ALL SELECT 7 AS id,'error 3456'
  UNION ALL SELECT 8 AS id,'Property Y'
  UNION ALL SELECT 9 AS id,'Location ab'
  UNION ALL SELECT 10 AS id,'error 12'
  UNION ALL SELECT 11 AS id,'error 56'
  UNION ALL SELECT 12 AS id,'Location de'
  UNION ALL SELECT 13 AS id,'error 12'
  UNION ALL SELECT 14 AS id,'error 56'
),
maxid AS
(
  SELECT MAX(id) as maxid FROM source
),
properties AS
(
  SELECT id, columnDesc FROM source WHERE columnDesc like 'Property%'
),
propertiesPlus AS
(
  SELECT id, columnDesc,
    isnull( (SELECT MIN(p2.id) FROM properties p2 WHERE p1.id < p2.id ),
    (SELECT maxid FROM maxid)) as nextid
  FROM properties p1
),
locations AS
(
  SELECT id, columnDesc FROM source WHERE columnDesc like 'Location%'
),
locationsPlus AS
(
  SELECT id, columnDesc,
    isnull( (SELECT MIN(l2.id) FROM locations l2 WHERE l1.id < l2.id ),
    (SELECT maxid FROM maxid)) as nextid
  FROM locations l1
),
errors AS
(
  SELECT id, columnDesc FROM source WHERE columnDesc like 'error%'
)
SELECT p.columnDesc as Property, l.columnDesc as Location, e.columnDesc as Error
FROM propertiesPlus p
  JOIN locationsPlus l ON l.id BETWEEN p.id and p.nextid
  JOIN errors e ON e.id BETWEEN l.id AND l.nextid
于 2013-11-14T18:53:48.483 に答える
0
with ds as (
select 1 as rowid, 'Property X' as columnDesc
union
select 2 as rowid, 'Location abc' 
union
select 3 as rowid, 'error 1234' 
union
select 3 as rowid, 'error 3456' 
union
select 4 as rowid, 'Property Y' 
union
select 5 as rowid, 'Location abc' 
union
select 6 as rowid, 'error 1234' 
union
select 7 as rowid, 'Location def' 
union
select 8 as rowid, 'error 12' 


)

,

rnProperty as (
select row_number() over (order by rowid) as rn , * from ds
where
columnDesc like 'Property%'),

rnLocation as (
select row_number() over (order by rowid) as rn , * from ds
where
columnDesc like 'Location%')



select 
rn.columnDesc, rnL.columnDesc, ds2.columnDesc

from rnProperty rn 
left join rnProperty rn2 on rn2.rn = rn.rn + 1
left join rnLocation rnL on rnL.rowid > rn.rowid and rnL.rowid < isnull(rn2.rowId,100000)
left join rnLocation rnL2 on rnL2.rn = rnL.rn + 1
left join ds ds2 on ds2.rowid > rnL.rowid and ds2.rowid < isnull(rnL2.rowid,1000000) and ds2.columnDesc like 'error%'
于 2013-11-14T17:28:54.883 に答える
0

私の意見では興味深い問題です。これがOracleのソリューションです。1 つのクエリと 2 つのサブクエリを使用するだけで、これまでに投稿された中で最も短いものだと思います。

WITH data1 AS
(
   SELECT 1 AS id,'Property X' AS columnDesc FROM DUAL
   UNION SELECT 2 AS id,'Location abc' FROM DUAL
   UNION SELECT 3 AS id,'error 1234' FROM DUAL
   UNION SELECT 4 AS id,'error 3456' FROM DUAL
   UNION SELECT 5 AS id,'Property Y' FROM DUAL
   UNION SELECT 6 AS id,'Location abc' FROM DUAL
   UNION SELECT 7 AS id,'error 1234' FROM DUAL
   UNION SELECT 8 AS id,'Location def' FROM DUAL
   UNION SELECT 9 AS id,'error 12'FROM DUAL
)
SELECT d2.columnDesc,d3.columnDesc,d.columnDesc
FROM data1 d, data1 d2, data1 d3
WHERE d.columnDesc NOT LIKE 'Property%'
AND d.columnDesc NOT LIKE 'Location%'
AND d2.id < d.id
AND d2.id = (SELECT max(id) FROM data1
             WHERE columnDesc LIKE 'Property%' AND id < d.id)
AND d3.id < d.id
AND d3.id = (SELECT max(id) FROM data1
             WHERE columnDesc LIKE 'Location%' AND id < d.id);
于 2013-11-14T18:31:25.273 に答える
0

すべての'error %'行を取得して as を使用columnDescし、指定された行の前にある最新のものとしてErrorMessage計算し、 maskに一致させることができます。これが私が話しているクエリです:PropertycolumnDesc'Property %'Location

SELECT
  Property     = (SELECT TOP (1) columnDesc
                  FROM atable
                  WHERE rowid < main.rowid AND columnDesc LIKE 'Property %'
                  ORDER BY rowid DESC),
  Location     = (SELECT TOP (1) columnDesc
                  FROM atable
                  WHERE rowid < main.rowid AND columnDesc LIKE 'Location %'
                  ORDER BY rowid DESC),
  ErrorMessage = columnDesc
FROM atable AS main
WHERE columnDesc LIKE 'error %'
;
于 2013-11-15T09:47:01.430 に答える