質問

私たちは、形のあるテーブルを持っています:

ID,Value1,Value2,Value3
1,2,3,4

私たちは、にこれを変換する必要があります。

ID,Name,Value
1,'Value1',2
1,'Value2',3
1,'Value3',4

(すなわちのUNIONなし)1つのSELECT文でこれを行うの巧妙な方法はありますか?列名値1、値2とVALUE3を固定し、一定である。

データベースは、Oracle 9iのである。

役に立ちましたか?

解決

このは、Oracle 10gの上で動作します:

select id, 'Value' || n as name,
       case n when 1 then value1 when 2 then value2 when 3 then value3 end as value
from (select rownum n
      from (select 1 from dual connect by level <= 3)) ofs, t

私は、Oracle 9iのは、再帰クエリを持っていたと思いますか?とにかく、私はそれがCASEをサポートしているかなり確信しているので、それは再帰的な問い合わせを持っていない場合でも、あなただけ行うことができます代わりに「OFS(すべてはデュアルから3を選択したすべてのデュアル組合から2を選択するデュアル組合から1を選択)」。再帰クエリを乱用することは、もう少し一般 - Oracleのです。 (行を生成するために組合を使用したけれども、他のDBにポータブルである)

他のヒント

union打撃を与えるます。

select ID, 'Value1' as Name, Value1 as Value from table_name union all
select ID, 'Value2', Value2 as Value from table_name union all
select ID, 'Value3', Value3 as Value from table_name

order by ID, Name

union allを使用すると、サーバは、(distinct操作で暗黙的である)unionを実行しないことを意味します。 (あなたのIDのは、うまくいけば、異なっている必要がありますので)これは、データとの違いを作るべきではありませんが、それは少しそれをスピードアップすることがあります。

あなたはこのようにそれを行うことができますが、それはかなりありません。

SELECT id,'Value 1' AS name,value1 AS value FROM mytable
UNION
SELECT id,'Value 2' AS name,value2 AS value FROM mytable
UNION
SELECT id,'Value 3' AS name,value3 AS value FROM mytable

合併する3つのselect文は、トリックを行う必要があります:

SELECT ID, 'Value1', Value1 AS Value
FROM TABLE
UNION
SELECT ID, 'Value2', Value2 AS Value
FROM TABLE
UNION
SELECT ID, 'Value3', Value3 AS Value
FROM TABLE

は、SQL Serverを使用している場合2005+、あなたはUNPIVOTを使用することができます。

CREATE TABLE #tmp ( ID int, Value1 int, Value2 int, Value3 int)

INSERT INTO #tmp (ID, Value1, Value2, Value3) VALUES (1, 2, 3, 4)

SELECT
    *
FROM
    #tmp

SELECT
    *
FROM
    #tmp
UNPIVOT
(
    [Value] FOR [Name] IN (Value1, Value2, Value3)
) uPIVOT

DROP TABLE #tmp

A UNION ALL、他の人が示唆しているとして、おそらくSQLのあなたの最善の策です。また、あなたの特定の要件が何であるかに応じて、フロントエンドでこれを取り扱いを検討する必要があります。

CTE構文は(私がTeradataの中でそれを実行した)Oracleの異なる場合がありますが、私はのみ1 2 3と4あなたが代わりに一時テーブルを使用することができ、テストデータを提供するために、CTEを使用しました。実際のselect文は、プレーンバニラSQLであり、それはすべてのリレーショナル・データベースになります。

SQL Serverの場合、UNIONの代替としてUNPIVOTを検討します:

SELECT id, value, colname
FROM #temp t
UNPIVOT (Value FOR ColName IN (value1,value2,value3)) as X

これは、同様に、列名を返します。私はXがために使用されているものをわからないんだけど、あなたはそれを残すことはできません。

これを試してください:

CTEは、4つの値を持つ一時テーブルを作成します。任意のデータベースであるとしてこれを実行することができます。

with TEST_CTE (ID) as

(select * from (select '1' as a) as aa  union all
select * from (select '2' as b) as bb  union all
select * from (select '3' as c) as cc  union all
select * from (select '4' as d) as dd )

select a.ID, 'Value'|| a.ID, b.ID
from TEST_CTE a, TEST_CTE b
where b.ID = (select min(c.ID) from TEST_CTE c where c.ID > a.ID)

ここでは、結果セットがあります:

1   Value1  2

2   Value2  3

3   Value3  4

お楽しみください!

いくつかの後づけます。

^^^ CTE構文はOracleで異なる場合があります。私は唯一のTeradataでそれを実行することができます。あなたは一時テーブルでそれを代用するか、Oracleの互換性を持たせるために、構文を修正することができます。 select文は、任意のデータベース上で動作する、プレーンバニラSQLです。

^^^もう一つは注意します。 IDフィールドが数値の場合は、「バリュー」とそれを連結するためにCHARにそれをキャストする必要があるかもしれません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top